Многопоточность в 1С, клиент-серверный вариант

21.06.15

Разработка - Механизмы платформы 1С

Многопоточность - это свойство системы выполнять одновременно более одной операции (в пределе - более одной программы), позволяя в ряде случаев добиться существенного роста производительности программного продукта...

Пролог.

Т.к. тема вызвала значительный интерес, хотелось бы дополнить ее ссылкой на раздел сайта Intel для разработчиков. В частности там говорится следующее:

Когда-то параллельное программирование было уделом только тех одиночек, которых интересовали задачи для огромных суперкомпьютеров. Но теперь, когда на многоядерных процессорах начали работать обычные приложения, параллельное программирование быстро становится технологией, которую должен освоить и уметь применять любой профессиональный разработчик ПО.

Введение.

Итак, многопоточность - это возможность выполнять несколько программ (потоков, threads) одновременно. Клиент-серверная архитектура 1С позволяет реализовать данную функцию через механизм фоновых заданий, при этом можно добиться существенного повышения производительности решений на платформе 1С.

Многопроцессорные сервера 1С являются устоявшимся фактом. Загрузка процессоров на серверах даже при достаточно интенсивной работе пользователей не редко держится на уровне 20-30%, т.к. клиентская часть 1С берет на себя функционал как минимум по отображению форм и, возможно, какую-то дополнительную нагрузку. В толстом же клиенте нагрузка на нее еще выше. Отсюда следует, что на серверах 1С существует неиспользованный вычислительный ресурс, который можно утилизировать.

Как это работает?

Для того, чтобы заставить 1С что-то делать параллельно, нужно обрабатываемые данные разбить на куски и постепенно скармливать создаваемым для этого потокам. Архитектурно это состоит из механизма получения порции данных - источника данных, механизма обработки данных - рабочей процедуре, и управляющей функции. 

В итоге у нас вырисовывается такая схема:

Управляющая процедура -> Поставщик данных (запрос)  -> Фоновое задание (порция данных) -> Отчет о выполнении -> Управляющая процедура.

Математическая модель будет выглядеть так:

  1. Получаем данные для обработки.
  2. Задаем количество фоновых заданий.
  3. Создаем массив для хранения фоновых заданий.
  4. Если количество стартованных фоновых заданий меньше, чем задано - п.5., иначе п.7.
  5. Стартуем фоновое задание и передаем ему оговоренное количество данных.
  6. Еще есть данные? Да - п.4, нет - выход (или подождем через ОжидатьЗавершения(МассивФЗ), после чего выйдем).
  7. Проверяем, есть ли в массиве задание, которое уже отработало. Если есть - п.5., иначе п.7.

Практическая задача.

Допустим, нам надо заполнить новый реквизит регистра сведений в соответствии с определенными условиями, которые могут быть отбором компоновки данных.

Дано:

  1. Регистр сведений "СферическиеКони" с измерением "Конь" (справочник "Кони") и ресурсом "ПлотностьСреды" (число 15,10) .
  2. Мы добавили параметр "СопротивлениеСреды", характеризующий сопротивление среды при максимальной скорости данного коня. Именно его и надо заполнить.

Предположим, что коней у нас много и заполнение без многопоточности займет много времени.

Опишем для начала рабочую процедуру:

Процедура ЗаполнитьСопротивлениеСреды(ИсточникДанных) Экспорт
    Для Каждого Ст ИЗ ИсточникДанных Цикл
        Рег = РегистрыСведений.СферическиеКони.СоздатьМенеджерЗаписи();
        Рег.Конь = Ст.Конь;
        Рег.Прочитать();
        Рег.СопротивлениеСреды = ПолучитьСопротивлениеСредыДляКоня(Ст.Конь.МаксСкорость, Ст.Конь.Радиус, Рег.ПлотностьСреды);
        Рег.Записать();
    КонецЦикла;
КонецПроцедуры

Данная процедура должна располагаться в общем модуле и быть экспортной, т.к. именно ее будет вызывать управляющая процедура, формируя фоновые задания.


Теперь опишем управляющую процедуру:

В принципе, управляющая процедура может и не быть процедурой - она может продолжить код получения данных

  МассивФЗ = Новый Массив;
  КоличествоЗаданий = 10;
  КоличествоДанныхДляЗадания = 100;
  МассивДанныхЗадания = Новый Массив;
  Для Каждого Ст ИЗ ИсточникДанных Цикл
      МассивДанныхЗадания.Добавить(Ст);
      Если МассивДанныхЗадания.Количество() = КоличествоДанныхДляЗадания Тогда
          Пока МассивФЗ.Количество() = КоличествоЗаданий Цикл
              Для Каждого ФЗ ИЗ МассивФЗ Цикл
                  // не помню, как получается задание, но как-то так - нет под рукой 1С
                  // смысл в том, чтобы проверить статус у запущенного задания, и если он не активен - освободить место в массиве ФЗ
                  Если НЕ ФоновыеЗадания.ПолучитьФоновоеЗаданиеПоГуид(ФЗ).Статус = СтатусыФЗ.Активно Тогда
                      МассивФЗ.Удалить(МассивФЗ.Найти(ФЗ));
                      Прервать; // выйдем из "бесконечного" цикла, когда хотябы одно из заданий закончилось
                  КонецЕсли;
              КонецЦикла; // ФЗ
          КонецЦикла; // КоличествоФЗ
          МассивПараметров = Новый Массив;
          МассивПараметров.Добавить(МассивДанныхЗадания);
          ФЗ = ФоновыеЗадания.Выполнить("ОбщийМодуль.ЗаполнитьСопротивлениеСреды", МассивПараметров);
          МассивФЗ.Добавить(ФЗ.ГУИД);
          МассивДанныхЗадания = Новый Массив;
      КонецЕсли; // КоличествоДанныхДляЗадания
  КонецЦикла;
  Если МассивДанныхЗадания.Количество() > 0 Тогда
      МассивПараметров = Новый Массив;
      МассивПараметров.Добавить(МассивДанныхЗадания);
      ФЗ = ФоновыеЗадания.Выполнить("ОбщийМодуль.ЗаполнитьСопротивлениеСреды", МассивПараметров);
  КонецЕсли;

Собственно, что мы сделали? Создали массив заданий и определили параметры обработки (количество потоков, количество данных в потоке). Далее заполнили массив данными, проверили, есть ли свободное место в массиве, если нет - дождались, и передали в фоновое задание для обработки. После чего поместили ГУИД ФЗ в массив.


Заключение.

Многопоточные вычисления все больше будут использоваться в дальнейшем, т.к. процессорная архитектура достигла пределов роста вверх по частоте - теперь она растет вширь по количеству ядер, объему памяти, емкости накопителей. Все это должно привести к прогрессу в области параллельных вычислений.

мультипоточность многопоточность параллелизм

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7459    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5947    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17674    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11227    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23763    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18835    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14735    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. andy23 470 22.06.15 00:34 Сейчас в теме
Регистр "СферическиеКони" звучит очень даже не плохо! А многопоточность тема хорошая, актуальная.
2. starik-2005 3087 22.06.15 01:10 Сейчас в теме
(1) andy23, как показывает практика, статьи о ней (многопоточности) и 1С появились аж в 2008-м году (то, что я смог найти - может что и раньше есть). Но и сейчас применение данного механизма доступно небольшому кругу посвященных ))
3. insurgut 208 22.06.15 06:55 Сейчас в теме
А по факту многопоточность так же внутри одного ядра выполняется?
7. starik-2005 3087 22.06.15 09:20 Сейчас в теме
(3) insurgut, в действительности фоновое задание запускается отлельным потоком на сервере 1с. Дальше потоком рулит ОС, выделяя ему память и ядро. Если процессорных ядер больше одного - происходит реальное распараллеливание, но даже на одном ядре код нескольких потоков может выполняться быстрее, т.к. waitы и sleepы - задержки - позволяют другим потокам в это время чтото делать.

В реальной жизни существует масса задач, скорость выполнения которых обратно пропорциональна количеству процессов (если их не больше количества ядер). Операции ввода-вывод, кстати, используют задержки, которые могут утилизироваться многопоточностью.
8. insurgut 208 22.06.15 10:07 Сейчас в теме
(7) если не ошибаюсь (что не исключено ;)), один процесс RPHOST выполняется на 1 ядре. И получается все зависит от того, какой RPHOST (если их несколько) будет выполнять тот или иной поток. Ситуация, что все они будут выполнятся на одном и том же рпхосте не исключена. И беда в том, что повлиять на это возможности уже нет (конечно и тут я могу ошибаться, поправьте если что). Но в любом случае, как вы сами и указали, все многопоточность сведется к одной последовательной операции чтения с диска. Но тут на помощь нам идет сам SQL, который возможно заранее все уже выгрузил в память.

P.S. Очень интересно было бы увидеть данные по приросту скорости выполнения при использовании приведенного метода многопоточности на реальной базе :)
9. pscorp 6 22.06.15 10:15 Сейчас в теме
(8) rphost выполняется не на одном ядре, он как раз может утилизировать все ядра. То, что это так можно убедиться запустив сервер 1с с одним процессом и увидев, что нагрузка попадает на все ядра. Из-за убеждения, что один процесс использует только одно ядро многие рекомендуют запускать рабочих процессов по числу ядер. На курсе 1с:Эксперт про это как раз рассказывают.
10. starik-2005 3087 22.06.15 10:23 Сейчас в теме
(8) insurgut, Вам, конечно, уже ответили, но я могу несколько дополнить. В случае вычисления в фоновом задании выражения на встроенном языке без обращения к ресурсам сервера SQL вы ограничены ресурсами сервера 1С, но если у происходит обращение к серверу СУБД - картина меняется. Т.к. АДО-механизм использует задержки при обращении к серверу, ожидая ответ, то второй поток даже на одном ядре может инициировать в это время еще одно соединение с сервером СУБД, утилизируя его вычислительные ресурсы. Отсюда мораль: если бОльшую часть работы мы перенесем на сервер СУБД, то можно запустить больше потоков на сервере 1С.
42. KroVladS 35 05.08.15 09:38 Сейчас в теме
(8) insurgut,
P.S. Очень интересно было бы увидеть данные по приросту скорости выполнения при использовании приведенного метода многопоточности на реальной базе :)

реальные результаты http://forum.infostart.ru/forum24/topic83924/message889711/#message889711
4. fancy 35 22.06.15 07:55 Сейчас в теме
Посмотрел код, получается, если массив заданий заполнен -ищем первое отработавшее задание и удаляем его из списка. Если же таких отработанных заданий в массиве будет несколько, то на мой взгляд будет оптимальнее их сразу все удалить, тогда для следующей порции данных уже не надо будет пробегать по массиву и искать неактивное задание (т. е предлагаю убрать оператор "Прервать")
n_mezentsev; +1 Ответить
5. WKBAPKA 215 22.06.15 08:46 Сейчас в теме
(4) fancy, это же пример. а по факту потом можно оптимизировать и оптимизировать. Автору спасибо за статью!
6. DoctorRoza 22.06.15 09:09 Сейчас в теме
Предложенная идея была озвучена в курсе по Оптимизации Бурмистрова Александра сколько - то там месяцев назад. Ничего нового, чего-то там записать в независимый РС несколькими ФЗ. При имеющейся архитектуре 1С да и перечню решаемых задач (ну рассчитайте себестоимость в несколько потоков!) многопоточность пока неактуальна!
dark_wolf; comol; newgluk; Gilev.Vyacheslav; spezc; SuhoffGV; +6 Ответить
45. avto1c 05.08.15 13:59 Сейчас в теме
(6) DoctorRoza, не актуальна пока вы не группа компаний по 20 - 50 пользователей в каждой. В противном случае появляются задачи для которых есть возможность и необходимость распараллеливания вычислений.
11. Jen1978 19 22.06.15 12:44 Сейчас в теме
Многопоточность можно применять по-разному, кто мешает к примеру запустить несколько потоков с разными функциями, которые к примеру получают разные данные из базы. На выходе, получим почти одновременно выполненные запросы и таблицы с ответами.
Пришлось как-то изучить Java. Только самые азы. Так вот там все построено на многопоточности.
12. genayo 22.06.15 20:09 Сейчас в теме
(6 Более того, я например сейчас работаю со специализированной конфой, написанной где-то в 2011 - 2012 году, где эта технология применяется в полный рост...
13. amon_ra 61 23.06.15 10:17 Сейчас в теме
А если взять в расчет файловую базу, то там как многопоточность организовывать? Через обработчик ожидания? Серверными все, конечно, понятно, а вот как обстоит дело с файловыми? Кто-нибудь пробовал?
14. starik-2005 3087 23.06.15 12:55 Сейчас в теме
(13) amon_ra, вряд ли при чтении из файловой базы удастся добиться ускорения при многопоточности, т.к. все упрется в клиентскую машину (ОС, диски, ядра, ...). Если ядер много, то что-то вычислить на встроенном языке без обращения к БД будет быстрее, но для этого уже механизм фоновых заданий вряд ли подойдет.
15. vde69 925 24.06.15 08:08 Сейчас в теме
вот тут обсуждал многопоточность http://www.forum.mista.ru/topic.php?id=743705
там даже с примером обратной связи от всех потоков....
16. starik-2005 3087 24.06.15 11:44 Сейчас в теме
(15) vde69, связи потоков и управляющей процедуры реализуются через метод "Сообщить" в ФЗ и функцию чтения сообщений у текущего потока. В описании схемы я как раз указал, что ФЗ может передавать данные управляющей процедуре, но в мат.модель и код я этого не добавил. Могу исправить и опубликовать статью о том, как это сделать (типа "прогресс-бар для мультипоточных вычислений") ))
17. dusha0020 1116 24.06.15 12:12 Сейчас в теме
Мне интереснее не сама многопоточность на фоновых заданиях, а механизмы обратной связи от потоков, или если хотите способы как сделать многопоточными не процедуры, а функции. Возврат через ВременноеХранилище не проходит. Что остается? ВременныйФайл, СообщениеПользователю, специальный регистр сведений. Может есть у автора более простые и красивые решения?
18. starik-2005 3087 24.06.15 13:27 Сейчас в теме
(17) dusha0020, все зависит от того, что Вы собираетесь с этим делать. "В оригинале" для синхронизации многопоточных вычислений применяются блокировки (mutex), позволяющие собирать результаты функций в некотором узле. Вопрос только в том, что далать с результатами. Если писать в регистр -то проще делать это сразу в потоке, если использовать для последующих вычислений, то, в принципе, для не сильно объемных данных писать через "Сообщить(ЗначениеВСтрокуВнутр(Результат))" в ФЗ, откуда уже разворачивать через "Для каждого Сообщение ИЗ ФЗ.ПолучитьСообщения() Цикл массивРезультатов.Добавить(ЗначениеИЗСтрокиВнутр(Сообщение.Текст)) КонецЦикла". В принципе, это уже тема для новой статьи - могу написать с примерами.
22. dusha0020 1116 24.06.15 16:04 Сейчас в теме
(18) Про писать в регистр и чтение сообщений ФЗ я знаю:) Интересовался более изящными способами в контексте 1С.
23. starik-2005 3087 24.06.15 16:41 Сейчас в теме
(22) dusha0020, а чем способ с сообщениями ФЗ не понравился? Вы до конца дочитали?
33. dusha0020 1116 25.06.15 08:45 Сейчас в теме
(23) Дочитал до конца, но давайте подумаем о практической пользе многопоточности. Например, если я выделяю некие промежуточные расчеты и собираю промежуточные результаты в параллельных потоках. Если промежуточный результат не велик и не сложен, то для большого объема вычислений нужно создать сотни и тысячи фоновых заданий, получить результаты и собрать их вместе. А параллельность выражается не количеством потоков, а количеством процессоров, то есть от такого деления реальной пользы будет не много за вычетом накладных расходов по сборке - разборке заданий и результатов.
Мне кажется правильнее делить задачу на 6-10 больших фрагментов и получать результаты большими порциями. Обработка 6-10 фрагментов в одном потоке, это, согласитесь, не обработка тысяч мелких ответов. Но вот в состоянии ли ЗначениеВСтроку() перенести ТЗ из 50 000 строк и 10-12 колонок числовых данных?
34. starik-2005 3087 25.06.15 09:19 Сейчас в теме
(33) dusha0020, не совсем верно. хотя тоже имеет право на существование. Накладные расходы на создание потока в принципе существенны, и при пустом цикле от 1 до даже 1000000 ощутимой разницы не будет, но при проведении документов, если регистры заполняются таким образом, что исключаются взаимоблокировки (читайте "библию 1С" - там об этом подробно написано, да и вообще в литературе по разработке приложений, использующих СУБД все это есть), выигрыш от мультипоточности весьма велик. Для нас оптимальным было 30-50 документов и 8-12 потоков. Средняя скорость проведения документа было примерно 0,1 сек против 0,9-1,1 секунды в один поток.
39. engineer74 27.07.15 21:09 Сейчас в теме
(18) Да с примерами интересна тема "способ с сообщениями ФЗ"
40. starik-2005 3087 28.07.15 22:48 Сейчас в теме
(39) engineer74, да, можно писать через сообщить(текст) в ФЗ. Если ща последнюю минуту не было сообщений - ФЗ зависло. У нас так ФЗ в регистр пишет, если время определенное прошло - система убивает задание и стартует новое, после чего чистит регистр от старого задания и размещает там информацию о новом. При старте ФЗ ему передается ключ, по которому оно себя в регистре ищет.

Кстати, ФЗ может иногда отваливаться - вместе с убиваемым менеджером кластера rphost'ом. У нас так печать работает в 5 потоков на Linux-сервера печати на базе CUPS. Т.к. они постоянно вылетали, и до включения полнейшего лога сервака мы не понимали, почему. В итоге сделали регистр, куда клались данные, отсортированные по потокам, и каждые 10 минут запускали задание, которое проверяло, есть ли фоновые задания с определенным именем. Если нет, и в регистре не пусто - запускало по новой и отправляло письмо админам. В итоге нашли проблему - одновременное подключение внешней компоненты печати ШК. Обернули в "мутекс" - все стало стабильно. Как-то отключили "допечатывание" - 2 недели проработало без этого - даже не заметили. Ни одно задание не отвалилось, ни один rphost не умер.
engineer74; +1 Ответить
48. DarkAn 1093 29.05.17 13:37 Сейчас в теме
(17) Если вопрос об обмене данных еще актуален - http://infostart.ru/public/626117/
19. spezc 792 24.06.15 14:42 Сейчас в теме
многопоточность в 1С это и есть сферический конь в вакууме. в отдельной взятой высосанной из пальца задаче вы его сможете применить, но не более того.
20. starik-2005 3087 24.06.15 14:52 Сейчас в теме
(19) spezc, обоснуйте свою позицию. У нас в организации многопоточность применяется от пакетного формирования печатных форм механизма автоматической печати и до обмена данными. Везде это приводит к весьма существенному улучшению производительности. Например, формирование печатных форм вместо трех часов занимает 50 минут (при пяти потоках).
21. karapuzzzz 63 24.06.15 15:50 Сейчас в теме
Это мой пример контроля помеченных на удаление с получением результата. Этот пример отработает не быстрее штатного т.к. функция "НайтиПоСсылкам()" и так многопоточная. Остальную часть этой обработки я так и не доделал. Ожидал, что прироста на поиске я не получу, а вот на удалении большого количества должен.
Если Многопоточность Тогда
		ЧислоСтрокВТаблице = Результат.Количество();
		// объем порции данных для обработки каждым потоком
		РазмерПорции = Цел(ЧислоСтрокВТаблице/ЧислоПотоков);
		// массив, где будут храниться фоновые задания
		МассивЗаданий = Новый Массив;
		МассивАдресовВХранилище = Новый Массив;
		Для НомерПотока = 1 По ЧислоПотоков Цикл
			// определяем индекс для начала обработки данных данным потоком
			// разные потоки обрабатывают разные части таблицы
			ИндексНачала = (НомерПотока - 1)*РазмерПорции;
			Если (НомерПотока = ЧислоПотоков) Тогда
				// если это последний поток, то он обрабатывает все оставшиеся данные
				// т.к. число потоков может не быть кратно количеству строк в таблице
				РазмерПорции = ЧислоСтрокВТаблице-(ЧислоПотоков*РазмерПорции)+РазмерПорции-1;
			КонецЕсли;
			МассивЗадания = Новый Массив;
			АдресВХранилище = ПоместитьВоВременноеХранилище(Неопределено);
			Для Счетчик = ИндексНачала По ИндексНачала+РазмерПорции Цикл
				МассивЗадания.Добавить(Результат[Счетчик])
			КонецЦикла; 
			// определяем массив параметров для процедуры
			НаборПараметров = Новый Массив;
			НаборПараметров.Добавить(МассивЗадания);
			НаборПараметров.Добавить(ИндексНачала);
			НаборПараметров.Добавить(РазмерПорции);
			НаборПараметров.Добавить(АдресВХранилище);
			// запуск фонового задания
			Задание = ФоновыеЗадания.Выполнить("МодульРегламентныхЗаданий.ПолучитьТаблицуНайденных", НаборПараметров);
			// добавляем задание в массив, чтобы потом отследить выполнение
			МассивЗаданий.Добавить(Задание);
			МассивАдресовВХранилище.Добавить(АдресВХранилище);
		КонецЦикла;
		// проверим результат выполнения фоновых заданий
		Если МассивЗаданий.Количество() > 0 Тогда
			Попытка
				ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
			Исключение
				Предупреждение("Ошибка поиска ссылок");
			КонецПопытки;
		КонецЕсли;
		
		ВсеНайденные = Новый ТаблицаЗначений;
		Для каждого ТекАдресВХранилище Из МассивАдресовВХранилище Цикл
			
			ТекТаблица = ПолучитьИзВременногоХранилища(ТекАдресВХранилище);
			Если ВсеНайденные.Колонки.Количество()=0 Тогда
				ВсеНайденные = ТекТаблица.СкопироватьКолонки();
			КонецЕсли; 
			
			Для Каждого ТекСтрокаДанные Из ТекТаблица Цикл
				НоваяСтрока = ВсеНайденные.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока,ТекСтрокаДанные);
			КонецЦикла;
			
		КонецЦикла; 
	Иначе
		ВсеНайденные = НайтиПоСсылкам(Результат);
	КонецЕсли;
Показать

И общий модуль:
Процедура ПолучитьТаблицуНайденных(Результат, ИндексНачала, РазмерПорции, АдресВХранилище) Экспорт
	ВсеНайденные = НайтиПоСсылкам(Результат);
	ПоместитьВоВременноеХранилище(ВсеНайденные, АдресВХранилище);
КонецПроцедуры
24. rtnm 616 24.06.15 22:59 Сейчас в теме
Управляющая функция жестко зациклена - не стоит демонстрировать такой код.
25. starik-2005 3087 24.06.15 23:00 Сейчас в теме
(24) rtnm, да что Ви говорите ))) Не стоит писать то, в чем Ви не понимаете )))
27. starik-2005 3087 24.06.15 23:22 Сейчас в теме
(25) для тех, кто все же не понял, как мы выходим из цикла, на всякий случай внес комментарии в код. Г-н rtnm, будучи хорошим специалистом, совершенно верно подметил, что цикл так просто не кончается. Но, слава Богу, есть программисты и получше. В данном конкретном случае цикл завершается оператором "прервать" после удаления первого отработавшего задания из массива фоновых заданий. После этого количество заданий будет больше, чем количество элементов массива, что приведет к выходу и из второго цикла.
Есть другой путь - процедура ОжиданиеЗавершения(массивФЗ). Но тогда мы теряем асинхронность. Мы запустили 10 заданий, они могут выполняться разное время, но ожидая завершения всех заданий мы теряем в производительности. надеюсь, теперь всем все понятно.
28. rtnm 616 24.06.15 23:31 Сейчас в теме
(27) вообще, речь о том, что код управляющей процедуры зря тратит процессорное время, гоняя свой цикл без устали.
Если управляющая функция находится на клиенте, то стоит присмотреться к ПодключитьОбработчикОжидания, а если на сервере (это ваш случай), то к ФоновыеЗадания.ОжидатьЗавершения с выставленным таймаутом
29. starik-2005 3087 24.06.15 23:35 Сейчас в теме
(28) rtnm, ну минусы-то Вы сильны ставить, а вот разобраться с проблемой не хотите, получается. Вот Вам ссылка:
http://www.forum.mista.ru/topic.php?id=626984
// Старый добрый WaitForMultipleObjects() в исполнении 1С вышел не айс. //

Вот такие "добрые дяди" с ожиданием завершения и удивляются, почему это эффективность маловата. Стоит также иметь ввиду, что получение фонового задания ждет ответа от сервера - в это время никаких инструкций не выполняется.
30. rtnm 616 24.06.15 23:45 Сейчас в теме
(29) минус вам за ваш слог в комментариях. Если бы вы в статье написали, что ФоновыеЗадания.ОжидатьЗавершения (с указанным таймаутом) работает как-то не очень, то моих комментариев вы бы и не увидели. По существу, вы проверяли что ФоновыеЗадания.ОжидатьЗавершения (с указанным таймаутом) сейчас работает как-то не очень?
31. starik-2005 3087 24.06.15 23:54 Сейчас в теме
(30) rtnm, во-первых, какое задание мы ожидаем? Все? Если все, то может так оказаться, что одно из заданий будет работать в 2 раза дольше, чем остальные. В итоге мы теряем вычислительные ресурсы сервера. И в 8.2. действительно до сих пор наблюдаются проблемы с работой ожидания завершения.
Во-вторых, использование бесконечного цикла не является моветоном в программировании. Читайте тут: https://ru.wikipedia.org/wiki/%D0%91%D0%B5%D1%81%D0%BA%D0%BE%D0%BD%D0%B5%D1%87%D0­%BD%D1%8B%D0%B9_%D1%86%D0%B8%D0%BA%D0%BB

/////////////////
Роль бесконечных циклов в Тьюринг-полноте языков[править | править вики-текст]
Любой цикл можно представить как бесконечный цикл, в теле которого есть проверка условия выхода и команда выхода из цикла.

Любая программа может быть написана при помощи:

бесконечных циклов;
команд выхода из цикла;
операторов ветвления (if-then);
последовательностью команд, исполняемых одна после другой;
Примечание: обратите внимание, что универсальный оператор GOTO (безусловный переход) не нужен, а достаточно специального оператора выхода из цикла, при этом, в случае n вложенных циклов потребуется n специальных операторов выхода из цикла (кроме небольшого количества языков с расширенным синтаксисом операторов выхода) или один оператор GOTO и одна метка.
/////////////////////////////

rtnm. учите мат.часть - это очень полезно. И запомните, если Вас всегда хвалят и всегда с Вами согласны - вы не развиваетесь. Я объективную развернутую критику крайне приветствую, но Ваше "Управляющая функция жестко зациклена - не стоит демонстрировать такой код." просто показывает, что в программировании, увы, Вы ничего не смыслите. Уж извините, но как есть.
26. starik-2005 3087 24.06.15 23:14 Сейчас в теме
(24) rtnm, уважаемый, я, конечно, понимаю, что не все специалисты - хорошие. Но не стоит свои личные проблемы понимания чужого кода принимать близко к сердцу. Будьте проще и люди к Вам потянутся (с) )))
32. rtnm 616 25.06.15 00:12 Сейчас в теме
Спасибо огромное, теперь то я все понял!!!
35. engineer74 26.07.15 19:38 Сейчас в теме
мне надо многопотоковость для загрузки данных из удаленныхточек
36. starik-2005 3087 26.07.15 21:11 Сейчас в теме
(35) engineer74, а в чем проблема?
37. engineer74 26.07.15 21:58 Сейчас в теме
(36) Может,уже обсуждали, Если фоновое задание зависло - как идентифицировать зависшее задание?
38. starik-2005 3087 27.07.15 10:55 Сейчас в теме
(37) engineer74, ну тут множество разных способов. Но важно выяснить, почему зависает задание. Причин тоже множество:
- запуск внешнего приложения - ФЗ будет ждать, пока оно завершит работу.
- запрос - ФЗ будет ждать, пока возвратятся данные.
- COM-объект - ФЗ будет ждать ответа.
- 1С тоже может повесить задание, но я таких примеров не встречал.
engineer74; +1 Ответить
41. KroVladS 35 05.08.15 08:56 Сейчас в теме
(0)
тема на инфостарте 2013г http://infostart.ru/public/182139/
книга знаний на мисте 2008г http://kb.mista.ru/article.php?id=696

а вообще очень полезная вещь, если кому то поможет пусть лучше дубли будут.
43. starik-2005 3087 05.08.15 11:58 Сейчас в теме
(41) KroVladS, да, о многопоточности пока не очень много статей. Так что новыми статьями в принципе продвигаем технологию, актуализируя "бренд" ))) Много - не мало!
44. starik-2005 3087 05.08.15 12:05 Сейчас в теме
(41) KroVladS, в принципе, отличие этой статьи в том, что здесь описывается технология скармливания пакетов с балансировкой нагрузки. Т.е. функции получения данных и их обработки разделены. Данные получаются потоком, достигая некоторого предела передаются в фоновое задание для обработки, при этом количество ФЗ ограничено определенным значением. Другими словами, здесь выделен отдельно управляющий заданиями механизм. В следующей статьея рассматриваю технологию создания "мьютекса" - в конкретном варианте - механизма выделения блока монопольного исполнения (critical code)
46. alex_4x 87 14.08.15 09:33 Сейчас в теме
1С Сделали работу с потоками на "отъ-ись" Типа реализовано, а то что хреново и не работает - это уже мелочи.

Должно быть как в NET -
1. определил спектр видимости переменных (в каждом потоке свой экземплар, или указанные потоки работают с одними и теми же переменными)
2. определил функции или процедуры, которые будут запускаться
3. запустил параллельно процедуры, с возможностью передачи управления по исключению или если всё хорошо (continuous)
4. ожидаем завершения нужных процедур (не в цикле!!!)
47. starik-2005 3087 14.08.15 17:39 Сейчас в теме
(46) alex_4x, есть функция ОжидатьЗавершения, в качестве аргументов передается список фоновых заданий. Чем плохо? .NET на клиенте выполняет многопоточный код, а 1С на сервере. Реализация вполне нормальная, способы обмена данными с потоком в принципе реализуемы. остается уточнить, какую именно задачу Вы хотите решить, и из этой предметной позиции уже говорить о сильных и слабых сторонах реализации в той или иной системе.
49. triviumfan 97 06.09.19 17:17 Сейчас в теме
Сергей, не подскажете, а как получать процент выполнения задания или заданий в обычном приложении?
Куда обычно скидывают состояния? Отдельную таблицу создавать как-то некрасиво. Хранилище общий настроек?
50. triviumfan 97 07.09.19 11:05 Сейчас в теме
(49) Разобрался. У фонового задания есть метод "ПолучитьСообщенияПользователю()", который получает то, что можно сообщить с помощью объекта "СообщениеПользователю".
starik-2005; +1 Ответить
51. raev72ru 25.05.20 13:51 Сейчас в теме
// не помню, как получается задание, но как-то так - нет под рукой 1С - В смысле?
вы что с телефона запостили? Ехали в маршрутке и решили, а не запостить ка мне про 1с в инфостарт.. ? (не смотря на то что с памятью у вас сомнения!)
Это не серьезно, ради чего это было сделано?
Я лично после этого комментария потерял уровень серьезности намерений вложить вклад в развитие программистов ищущих решения, не хотелось бы чтобы вы были примером им. Если сможете то старайтесь!
52. starik-2005 3087 26.05.20 18:13 Сейчас в теме
(51)
Это не серьезно, ради чего это было сделано?
Я как Эйнштейн - не заучиваю физических констант. Все статьи пишу на основе опыта, но не гляжу в 1С.

Более того, стараюсь, чтобы тот, кто осилит чтение статьи, смог это сделать, не тупо копируя код, а понимая, что этот код делает. Для этого нужно, чтобы код был написан не автором и скопирован, а читателем.

Статья рассказывает о многопоточности, о принципах, а не дает код, который любой дурак скопирует куда-то, а потом будет гадать, почему же у него что-то не получилось. Статья излагает мат.часть, которую нужно прежде всего понять. И код получения фонового задания - это не тот код, который должен вызывать подобную реакцию, а то напрашивается мысль, а понял ли читатель вообще хоть что-то?
53. raev72ru 27.05.20 07:59 Сейчас в теме
(52) Какой интересный подход. Решение завернутое в дополнительный труд. Если к примеру скопировать можно было и вставить, за тем отладчиком понять что и как работает и по понятой модели написать свой код. То тут же нужно понять модель визуализируя результаты в уме. Интересный подход, время не экономит но развивает мышление. Ясно. Спасибо за пояснения.
54. starik-2005 3087 27.05.20 12:59 Сейчас в теме
(53)
Спасибо за пояснения.
Всегда пожалуйста.
55. avbolshakov 28.11.22 16:20 Сейчас в теме
(54) а подскажите, пожалуйста - у меня не выходит что-то повторить пример. На файловой ведь тоже должно сработать? Я правда просто создаю элемент справочника в учебной каркасной базе (платформа не учебная). Должно ведь появляться несколько фоновых заданий в списке Активных пользователей? Фоновые появляются. но всегда по одному (номера сеансов меняются). В МассивДанныхЗаданий я просто добавляю число, а в процедуре исполняющей циклом обхожу этот массив просто создавая элемент. Что я делаю не так?

upd Все отрабатывает, но обычным способом все равно выходит быстрее. Вроде и логично - я делаю то же самое что просто создавая элемент, но фоновое всегда одно. те как-будто они по очереди создают.
Прикрепленные файлы:
56. starik-2005 3087 28.11.22 19:34 Сейчас в теме
(55) На файловой только одно фоновое задание работает за раз.
avbolshakov; +1 Ответить
57. Andq 19.09.24 11:52 Сейчас в теме
Спрошу здесь. В проф версии доступно 12 физических ядер (не на виртуалке). Подчеркивается, что именно физических. По ядрам понятно, что с потоками? Если я заменю 12-ядерный процессор с 12 потоками на 12-ядерный с 24 потоками, это что-то изменит?
Оставьте свое сообщение