Заказы на доработку 1С (сервис удаленной работы)

Хранилище

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

Здравствуйте, гость ( Вход | Зарегистрироваться )



> Многопоточность как способ ускорения некоторых процедур          
Vofka Подменю пользователя
сообщение 29.04.13, 10:42
Сообщение #1

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13955
Из: Киев
Спасибо сказали: 4519 раз
Рейтинг: 3641.2

Платформа 1С:Предприятие 8 обладает необходимыми инструментами для обеспечения многопоточности, но на практике про эти инструменты незаслуженно забывают.

Конечно, многопоточность – это не панацея, но это хороший способ для:

1) уменьшения длительности выполнения длительных процедур (в некоторых ситуациях - на порядки!);

2) повышения утилизации ресурсов оборудования.

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

Пара примеров:

1) Существует несколько сотен магазинов, работающих на самописном ПО, и единая база в головной компании, куда ежедневно выгружаются транзакции по продажам. Загрузка инициируется пользователем по кнопке и занимает длительное время, т.к. магазинов много и транзакций приличное количество, а обработка пакетов данных идет последовательно.

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

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

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

В этой ситуации можно было бы распараллелить выгрузку данных – одновременно выгружать данные по разным магазинам. Это существенно ускорит процесс и позволит в полной мере ощутить эффект от мощного железа.

Инструменты встроенного языка для выполнения многопоточной процедуры.

Наиболее эффективно организовать многопоточность можно с помощью Фоновых заданий (не путать с регламентными заданиями).
Необходимо циклически формировать порции фоновых заданий и дожидаться их завершения.

Пример кода для второго случая (выгрузка большого массива данных порциями):

1) Процедура, инициирующая многопоточное выполнение кода:

 Процедура КнопкаВыполнитьНажатие(Кнопка)

     //указывает число потоков, которые будут запущены одновременно
     ЧислоПараллельныхПотоков = 10;

     МассивЗаданий = Новый Массив;

     Запрос = Новый Запрос(
     "ВЫБРАТЬ РАЗЛИЧНЫЕ
     |    ПартииТоваровНаСкладах.Склад
     |ИЗ
     |    РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
     |ГДЕ
     |    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2");
     Запрос.УстановитьПараметр("Дата1", ДатаНачала);
     Запрос.УстановитьПараметр("Дата2", ДатаОкончания);

     Результат = Запрос.Выполнить().Выгрузить();

     Для каждого Стр из Результат Цикл

         МассивПараметров = Новый Массив;
         МассивПараметров.Добавить(ДатаНачала);
         МассивПараметров.Добавить(ДатаОкончания);
         МассивПараметров.Добавить(Стр.Склад);

         Задание = ФоновыеЗадания.Выполнить("ВыгрузкаДанныхНаСервере.ВыгрузитьДанныеПоПартиям", МассивПараметров);

         МассивЗаданий.Добавить(Задание);

         Если МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
             Попытка
                 ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
             Исключение
             КонецПопытки;
             МассивЗаданий.Очистить();
         КонецЕсли;

     КонецЦикла;

     Если МассивЗаданий.Количество() > 0 Тогда
         Попытка
             ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
         Исключение
         КонецПопытки;
         МассивЗаданий.Очистить();
     КонецЕсли;

     Сообщить("Время выполнения процедуры - " + (ТекущаяДата() - ВремяНачала) + " с.");

КонецПроцедуры


2) Процедура, которую непосредственно выполняет фоновое задание (основная логика):

Общий модуль «ВыгрузкаДанныхНаСервере», выполняемый на сервере:

Процедура ВыгрузитьДанныеПоПартиям(ДатаНачала, ДатаОкончания, Склад) Экспорт

     Запрос = Новый Запрос(
     "ВЫБРАТЬ
     |    *
     |ИЗ
     |    РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
     |ГДЕ
     |    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2
     |    И ПартииТоваровНаСкладах.Склад = &Склад");

     Запрос.УстановитьПараметр("Дата1", ДатаНачала);
     Запрос.УстановитьПараметр("Дата2", ДатаОкончания);
     Запрос.УстановитьПараметр("Склад", Склад);

     Результат = Запрос.Выполнить().Выгрузить();

     Для каждого Стр из Результат Цикл
         //Что-то делаем с данными
     КонецЦикла;

КонецПроцедуры


При этом следует учесть, что к выбору числа параллельных заданий нужно отнестись ответственно – если запустить их даже несколько десятков, то велика вероятность «повесить» и сервер приложений, и сервер СУБД.

[необходимо зарегистрироваться для просмотра ссылки]

Спасибо сказали: Acid, zay,

Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 16.04.24, 8:20
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!