Многопоточное выполнение процедуры с помощью ДлительныеОперации

26.02.23

Разработка - БСП (Библиотека стандартных подсистем)

В публикации: Приведен шаблон для запуска многопоточной операции для различных вариантов размещения многопоточной операции, в том числе в модуле объекта внешней обработки, встроенной в справочник Дополнительные отчеты и обработки; Представлен вариант корректного отображения прогресса многопоточной операции; Приведены замеры, демонстрирующие целесообразность использования нового механизма для увеличения производительности.

Скачать файлы

Наименование Файл Версия Размер
Многопоточное выполнение процедуры
.epf 15,65Kb
13
.epf 15,65Kb 13 Скачать

Введение

Недавно столкнулся с необходимостью увеличить скорость работы одной внешней обработки. Оказалось, что начиная с версии БСП 3.1.6 появился новый функционал. 

Новые возможности для разработчиков в версии 3.1.6

Базовая функциональность

  • Для ускорения выполнения длительных операций предусмотрена возможность выполнить обработчик длительной операции в несколько потоков. Для этого необходимо:
    • Разделить данные на наборы, где каждый элемент набора будет обработан в отдельном фоновом задании.
    • Из программного интерфейса общего модуля ДлительныеОперации для запуска процедуры длительной операции вызвать функцию ВыполнитьПроцедуруВНесколькоПотоков (или ВыполнитьФункциюВНесколькоПотоков), передав третьим параметром сформированный набор данных. Подробное описание параметров см. в комментарии к этим функциям.
    • Максимально допустимое количество одновременно работающих фоновых заданий может быть задано администратором в разделе Администрирование - Общие настройки - Производительность
    • В файловой информационной базе и при работе в модели сервиса длительные операции всегда выполняются в один поток.
    • Пример см. в демонстрационной конфигурации в форме ЗагрузкаАдресногоКлассификатора регистра сведений АдресныеОбъекты.

В описании функции ВыполнитьПроцедуруВНесколькоПотоков (или ВыполнитьФункциюВНесколькоПотоков, но для удобства не буду разделять) описано, что код который будет выполняться в фоне должен быть в:

  1. В общем модуле ("МойОбщийМодуль.МояПроцедура")
  2. Модуле менеджера объекта ("Отчет.ЗагруженныеДанные.Сформировать")
  3. Модуле обработки ("Обработка.ЗагрузкаДанных.МодульОбъекта.Загрузить")

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

Цели

Перед тем как приступать к реализации, поставим цели, которых хотим достичь в рамках публикации.

  1. Публикация должна ответить читателю на ряд вопросов:
  • Как многопоточно запустить процедуру расположенную в серверном общем модуле?
  • Как с помощью ДлительныеОперации запустить процедуру модуля объекта внешней обработки?
  • Как многопоточно запустить процедуру модуля объекта внешней обработки?
  • Как отобразить прогресс многопоточной операции?
  1. В публикации должны быть продемонстрированы замеры производительности в зависимости от кол-ва потоков, наглядно показан выигрыш в производительности

Цели поставлены, приступим к реализации.

Реализация

Разработка проводилось на демонстрационной базе БСП версии 3.7.1.327. 

Начнем с краткого описания того, что будет делать наша обработка:

  1. Получаем выборку ссылок на N-ое кол-во документов _ДемоПоступлениеТоваров
  2. Разбиваем ее на порции размером N/k, где k - кол-во потоков
  3. Формируем структуры параметров для функции ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков
  4. Запускаем длительную операцию которая поменяет в каждом обрабатываемом документе значение реквизита Комментарий

 

Форма обработки

 

 

Модуль объекта

 

Процедура ниже будет запускаться многопоточно

 
Модуль объекта

 

Модуль формы

 

Первым делом ответим на вопрос "Как в длительной операции запустить процедуру модуля объекта внешней обработки?":

 
Как с помощью ДлительныеОперации запустить процедуру модуля объекта внешней обработки?

 

И реализуем базовую функциональность для отображения прогресса

 
 Прогресс
 

Теперь ответим на вопрос "Как многопоточно запустить процедуру модуля объекта внешней обработки?" и "Как многопоточно запустить процедуру расположенную в серверном общем модуле?": 

 
 Многопоточный запуск
 

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

 

 

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

1. В процедуру  ПрогрессВыполнения попадает структура длительной операции (см. ДлительныеОперацииКлиент.ПараметрыОжидания) и что важно - в ключе ИдентификаторЗадания этой структуры, содержится именно идентификатор основной длительной операции.

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

Синтезируем из этих фактов процедуру которая корректно отображать прогресс многопоточной операции, а если точнее подправим процедуры ПрогрессВыполнения и ПрочитатьПрогресс:

 
Улучшенный прогресс

 

Полный код модуля формы

 

 
 Полный код модуля формы

 

Замеры производительности

 

Были произведены замеры производительности в зависимости от кол-ва потоков. Результаты для разного кол-ва обрабатываемых документов на графиках

  

  

 

 

Из графиков видно, что вне зависимости от кол-ва обрабатываемых документов, использование даже двух потоков на данном конкретном примере дает выигрыш в производительности примерно в 2 раза.

 

Выводы

 

В публикации:

  • Приведен шаблон для запуска многопоточной операции для различных вариантов размещения многопоточной операции, в том числе в модуле объекта внешней обработки, встроенной в справочник Дополнительные отчеты и обработки;
  • Представлен вариант корректного отображения прогресса многопоточной операции;
  • Приведены замеры, демонстрирующие целесообразность использования нового механизма для увеличения производительности.

 

P.S.

 

  • Еще публикации по теме:

Многопоточный режим выполнения процедуры с помощью методов БСП - примеры разработки

Гарантированно рабочий пример использования длительных операций на БСП с отображением прогресса. [Часть 1]

Многопоточность как способ ускорения некоторых процедур

Как ускорить 1С – Многопоточная обработка данных

  • Многопоточность работает только в клиент-серверном варианте работы
  • Обратите внимание на константу Кол ичествоПотоковДлительныхОпераций, по умолчанию значение 0 и больше 3 потоков запущено не будет. (см. ДлительныеОперации.ДопустимоеКоличествоПотоков)
  • Весь код по теме представлен в публикации, в приложенной обработке реализован тестовый стенд для этой статьи с замерами времени, построением по ним графика и тп

 

 

 

Многопоточно ДлительныеОперации ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков ДлительныеОперации.ВыполнитьФункциюВНесколькоПотоков ВыполнитьПроцедуруМодуляОбъектаОбработки прогресс распараллеливание фоновые задания БСП

См. также

Ограничение видимости дополнительных отчетов по пользователям для БСП

Роли и права БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Розница 3.0 Абонемент ($m)

Часто нужно ограничить дополнительные отчеты по видимости для разных пользователей. В "варианте отчета" для дополнительного отчета (БСП) можно указать конкретных пользователей, которым доступен данный вариант. Но данная настройка не срабатывает, т.к. варианты дополнительных отчетов считаются "предопределенными".

1 стартмани

14.09.2023    250    1    itmind    0    

9

Оптимизация персонализированных рассылок отчетов в БСП

Email рассылки БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Абонемент ($m)

Представленная в публикации разработка позволяет оптимизировать персонализированную рассылку отчетов БСП за счет предварительной выборки получателей отчетов.

1 стартмани

10.07.2023    801    0    Sirruf    0    

3

Снова об использовании ТекущаяДата() на клиенте и на сервере и о работе в разных часовых поясах

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

Можно ли применять ТекущаяДата() вопреки требованиям стандартов 1С? Безопасно ли использование функции ОбщегоНазначенияКлиент.ДатаСеанса() из БСП? Как правильно поступать при работе пользователей в разных часовых поясах?

24.04.2023    5524    Alxby    26    

44

Печать в WORD при помощи БСП. Вывод уникальных ссылок в строки таблицы

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

Пример вывода уникальных ссылок в строку таблицы макета WORD при печати с помощью БСП. Может быть полезна при создании интерактивных прайсов.

03.04.2023    1238    user1575928    0    

18

Учим БСП печатать активные ссылки и подложку в документе WORD

БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

1 стартмани

13.03.2023    1621    3    user1575928    0    

6

Пример многопоточной обработки (БСП)

HighLoad оптимизация БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

13.02.2023    7496    4    echo77    8    

83
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Sergant 52 27.02.23 11:40 Сейчас в теме
Запуск потока в голанг - go ИмяФункции().
А теперь живите с этим. :)
SquizzyMan; +1 2 Ответить
6. alex_sayan 27.02.23 15:43 Сейчас в теме
(1) в голанге многопоточно шло из коробки. А сами потоки очень легковесные. Тут как бы и сравнивать даже некорректно
7. Sergant 52 27.02.23 15:45 Сейчас в теме
(6) Как бы сравнивать корректно, некорректно - утюги с пирогами. 1С унылый малопоточный тормоз.
LsrGroup; +1 Ответить
20. JohnyDeath 301 03.03.23 15:07 Сейчас в теме
(7) вы, наверное, и на форум ГО-разработчиков заходите в тему, где они создают таблицы БД с индексами и формы списков и объектов к ним, контроль целостности и т.п. а потом добавляете комментарий:
"В 1с достаточно добавить Справочник в метаданные. Живите теперь с этим!"
;)
21. Sergant 52 03.03.23 15:27 Сейчас в теме
(20) А также они не имеют такого классного конструктора запросов или СКД. И поверьте - явашники и гошники, бывшие 1Совыцы, очень сильно страдают.
14. more 15 01.03.23 10:29 Сейчас в теме
(1)А не похоже ли это на человека, который сравнивает велосипед с бульдозером? типа "Велосипед транспорт и ехать на нем можно и через подземный переход на нем можно, а бульдозер ничего из этого не умеет. Вот и живите с этим. :)"
Может быть вы сможете написать ERP на вашем голанг и мы посмотрим как это получится? Ну а что, вдруг будет лучше - и весь мир перейдет на вашу ERP, Станете богатым человеком. Я придерживаюсь такого мнения - есть конструктивная идея - пишем разработчику продукта (в нашем случае 1С). Есть новый функционал в 1С, ознакомились - сказали спасибо, и пошли дальше (работать, зарабатывать, внедрять один из лучших бизнес продуктов на нашем рынке)
Olenevod; JohnyDeath; sa1m0nn; serg_gres; nyam-nyam; +5 Ответить
15. Sergant 52 01.03.23 11:23 Сейчас в теме
Могу лишь повторить - 1С унылый малопоточный тормоз (признать неприятно некоторым). Go язык - быстродействие и многопоточность это его ДНК. Сравнивать могу, как может сравнить экскаваторщик на чем ему быстрее будет добраться домой на обед - на велосипеде или на экскаваторе). Мои слова не отменяют великолепие 1С в части быстрой разработки бизнес приложений.
16. Sergant 52 01.03.23 19:23 Сейчас в теме
После таких кто говорит про некорректность сравнения потом другие переписывают весь код или уходят к другим вендорам. Salesforce: Why we ditched Python for Google's Go language in Einstein Analytics.
23. siamagic 13.03.23 11:53 Сейчас в теме
(1)Для внешнее обработки 2 строчки на клиенте, 4 на сервере. Если убрать вызов с клиента и сильно захотеть то будет две строки на сервере.
Живи с этим.
2. ImHunter 277 27.02.23 12:31 Сейчас в теме
(1) ФоновыеЗадания.Выполнить("ИмяМетода") - не сильно сложнее.
Автор таки по-сложнее кейс реализует.
корум; SnubbyAston; +2 1 Ответить
4. Sergant 52 27.02.23 14:03 Сейчас в теме
(2) Так и знал что это скажут.
А перед вызовом сколько кода написано? На уровне днк языка или общих модулей :)
О тот как через сообщения пользователя 1С кидает уведомления о прогрессе выполнения задания - я молчу. Меня чуть не стошнило.

Работаем товарищи. Все что не может платформа 1С - Будем делать мы!
3. KUAvanesov 27.02.23 13:20 Сейчас в теме
(1) ну там еще синхронизация через каналы, мьютексы итп. Не так уж и просто все.
Но то что GO запустит 100500 горутин и не помрет а 1с 8-10 и больше не стоит - это факт).

PS все же хорошо, что 1с в бсп реализует то, что раньше приходилось писать самостоятельно, значит прислушиваются, присматриваются к коду, который пишут на 1с. Я вот уже привык использовать длительные операции, с отладкой удобно же сделали через "/РежимОтладки".
19. serg_gres 152 02.03.23 12:54 Сейчас в теме
(3)
Но то что GO запустит 100500 горутин и не помрет а 1с 8-10 и больше не стоит - это факт).


Хоть 100500, хоть миллиард, а если действия, которые производятся в фоне связаны с БД,
то 100500 потоков на GO не будут быстрее, чем 1С с ее 10-ю потоками.

Я надеюсь никто ведь не думает, что 100500 потоков GO одномоментно и мгновенно
способны произвести записи в таблицу SQL ?

Если в фоне нужно производить какие-то, например, вычисления в памяти,
то 1С однозначно будет проигрывать, потому что вся ее инфраструктура тяжеловесна
(это и динамическая типизация, и запуск полноценного сеанса в потоке и т.д. и т.п.).
Но таких задач в среде 1С не особенно то часто и бывает,
поэтому то, что сейчас реализовано в 1С - в максимальной степени отвечает сфере применения платформы.
И в этой среде конкуренты не то что лучше, они хуже 1С по совокупности параметров.
5. ImHunter 277 27.02.23 14:10 Сейчас в теме
(4) Нутк и сравнивать горутины с фоновыми заданиями 1С - мягко говоря, некорректно. Да, легкого аналога горутин в 1С нет.
8. alexey_kurdyukov 141 27.02.23 18:02 Сейчас в теме
А почему два потока в три раза быстрее одного? Я ожидал прирост где-то в 1.8.
starik-2005; echo77; +2 Ответить
10. starik-2005 2871 28.02.23 15:42 Сейчас в теме
(8)
А почему два потока в три раза быстрее одного?
Я вообще ожидал в 18 раз, но математика - не мое )))
egoriy111; +1 Ответить
11. alexey_kurdyukov 141 28.02.23 15:44 Сейчас в теме
(10) да почему в три раза-то, должно быть какое-то объяснение!
12. egoriy111 77 28.02.23 20:12 Сейчас в теме
(11)
на данном конкретном примере

Из возможных причин почему 3, хотя я тоже ожидал в районе двух: хороший сервак, с 12-ти ядерным процессором, на сервере работало в момент тестов 1,5 пользователя включая меня. Как именно там распределилась нагрузка - не знаю. Но есть куда копать
9. echo77 1829 27.02.23 19:50 Сейчас в теме
Еще вот такой шаблон есть https://infostart.ru/public/1808052/
13. alexey_kurdyukov 141 01.03.23 03:13 Сейчас в теме
Можете повторить замеры, добавив выполнение работы синхронно, в том же потоке, без заданий?
egoriy111; +1 Ответить
17. egoriy111 77 01.03.23 20:48 Сейчас в теме
(13) Спасибо за идею, почему то такая очевидная вещь в голову не пришла) Действительно, правильнее сравнивать выполнение без фона, с 2мя и большим кол-вом потоков. Я запустил код для 1000 документов без фона и получил время выполнения 1.32 мин, это уже ближе к тому что ожидалось. Сделаю замеры для других и поправлю графики
18. ImHunter 277 02.03.23 10:05 Сейчас в теме
(14) Больше похоже на сравнение электросамоката с электропогрузчиком. Да, технически, можно что-то посравнивать. Но, практически, в таком сравнении нет никакого смысла.
22. soldatof 07.03.23 11:47 Сейчас в теме
А как же ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьКомандуВФоне ? Кажется еще с БСП 3.1.4 есть.
24. Quantum81 6 12.04.23 11:23 Сейчас в теме
Огонь!
Стеб с GO считаю оправданным, т.к. уже пора все это выносить в платформу, а не колхозить на базе фоновых. Имхо.
Оставьте свое сообщение