Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Многопоточность в 1С (число прочтений - 8283 )
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Многопоточность в 1С
12. Ноября 2007 :: 06:00
Печать  
А не вернуться ли нам к теме многопоточности? Улыбка

Насколько я знаю, есть как минимум два типа многопоточности:

Кооперативная. Реально в системе есть только один поток выполнения. Многопоточность эмулируется квазипотоками. Переключение между квазипотоками происходит по воле каждого из них: при помощи вызова специальной функции или при любом обращении к системе. Такая система многопоточности в Win 3.11. Такую систему наиболее реально построить для модулей 1С. Ведь 1С не рассчитана на многопоточность. А кооперативная многопоточность использует только один поток выполнения, поэтому не происходит одновременного обращения к общим данных из разных потоков. Идеальная многопоточность для 1С выглядела бы, наверное, так:

Код
Выбрать все
Перем гШедулер;

Процедура Обработка ()
гШедулер = СоздатьОбъект ("Шедулер");
гШедулер.ЗарегистрироватьМодуль ();

Для Ч = 1 По 10000 Цикл
... какая-то обработка...
гШедулер.ОтдатьУправление ();
КонецЦикла;
КонецПроцедуры
 



В шедулере регистрируются модули. Во время выполнения модуль, получивший управление, делают некую часть своей работы и вызывает ОтдатьУправление (). Шедулер смотрит, есть ли еще модули, и отдает управление следующему в очереди. Если других модулей нет, то управление получает первый.

Не уверен, что такой способ сделать реально. Я просто не знаю деталей. Может быть, кто-то знает лучше?

Если нельзя получить "идеальный" способ выполнения, то наверняка можно пойти более реальным путем. Например, так:
Код
Выбрать все
Перем гШедулер;

Процедура Выполнить ()
гШедулер = СоздатьОбъект ("Шедулер");
гШедулер.ЗарегистрироватьМодуль ("Обработка");
гШедулер.Старт ();
КонецПроцедуры

Функция Обработка ()
... некая обработка...
Если РаботаОкончена Тогда
 Возврат 0;
Иначе
 Возврат 1;
КонецЕсли;
КонецФункции
 



В этом случае берем, например, тело цикла обхода результата запроса и выносим его в отдельную функцию. Т.е. чтобы один вызов этой функции соответствовал выполнению одной итерации цикла. В шедулере региструется несколько модулей с несколькими подобными функциями. Шедулер по методу "Старт" тупо последовательно вызывает все зарегистрированные функции. Если какая-то функция возвращает 0, то эта функция исключается из цикла выполнения.

В принципе, такую многозадачность можно сделать и штатными методами. Однако отдельный шедулер дает следующие выгоды:
- Модулям не обязательно знать друг о друге. Если использовать только штатные методы, то модули, скорее всего, будут "завязаны" друг на друга, что плохо влияет на модульность.
- Шедулер может при "переключении контекстов" заставить 1С обработать поступившие оконные сообщения. Что дает возможность использовать кнопки и другие элементы диалога 1С. Это, например, даст возможность прервать выполнение обработки цивилизованным методом - по кнопке "Отмена", а не по Esc. Также у пользователя появится возможность влиять на выполнение обработки в процессе выполнения.

В общем-то, подобная кооперативная многозадачность мало, что дает полезного Улыбка В основном это большая интерактивность системы, возможности многопроцессорной обработки никак не используются. Хотя кому как Улыбка Да! В принципе, шедулер частично может быть реализован в виде специального класса 1С++.

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

Однако, использование многопоточности возможно для ВК. 1С собрана, насколько я понимаю, с использованием многопоточной CRT. Следовательно операции выделения/освобождения памяти могут выполняться конкурентно из разных потоков, без опасения испортить хип. Если это не так, то, в принципе, можно перейти в ВК на отдельный хип, не зависимый от 1С.

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

Еще применение. Получение данных от MSSQL работает довольно хитрым образом. На клиент уходят только реально запрошенные данные. Я еще как-то удивлялся, когда запустил запрос, который должен был практически вернуть содержимое таблицы в гигабайт весом. Этот запрос выполнился практически мгновенно. И только когда дело дошло до выборки результата наступили долгожданные тормоза Улыбка Так вот. Выборку порций данных можно поместить в отдельный поток выполнения. А в основном потоке можно выводить уже полученную порцию в отчет.

Основной вопрос в случае с индексированной таблицей: использование CValue. Там CValue используется очень активно. Я просто не знаю, не происходит ли при обработке CValue обращений к каким-нибудь общим данным? Если не происходит, то переделок может потребовать очень мало. В основном это блокировка при доступе к данным ИТ в момент, когда обработка в другом потоке еще не завершилась. В этом случае можно использовать какой-то объект синхронизации, чтобы при обращении из основного потока основной поток останавливался и ждал завершения второго потока.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #1 - 12. Ноября 2007 :: 06:05
Печать  
Т.е. все выглядит примерно так
Код
Выбрать все
ИТ = СоздатьОбъект ("ИндексированнаяТаблица");
... заполняем ИТ...
ИТ.Группировать (...);
... делаем какую-то работу...
ИТ.ВыбратьСтроки ();
 



На строке "ИТ.ВыбратьСтроки ()" основной поток засыпает и ожидает завершения выполнения обработки "Группировать". Если этап "делаем какую-то работу" отсутствует, то по времени выполнения многопоточный вариант никак не отличается от времени однопоточного варианта. Потому что после вызова "Группировать" мы сразу заблокируем основной поток на методе "ВыбратьСтроки" и будем стоять столько времени, сколько понадобится на завершении группировки.
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Многопоточность в 1С
Ответ #2 - 12. Ноября 2007 :: 10:14
Печать  
Ого, вот это я понимаю!  Улыбка

У меня пока только две мысли возникло:
1. Интересно загрузить дополнительные ядра (коих будет все больше) - так что первый вариант не катит.
2. В самой тяжелой по времени группировке (по группам справочника) активно используется LinkContext - тут наверняка будут проблемы во втором потоке.

А так да, все так и есть.
И если не в ИТ, то где-то еще такую модель можно будет забацать.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #3 - 12. Ноября 2007 :: 11:24
Печать  
Если уж затронули тему "многопоточности" то не пропустите такой момент:
табличноеПоле подтормаживает на местах с дохлой сеткой и замораживает систему во время зачерпывания данных.
Может пока пойти в этом благодарном направлении? Подмигивание
  
Наверх
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Многопоточность в 1С
Ответ #4 - 12. Ноября 2007 :: 13:12
Печать  
trdm писал(а) 12. Ноября 2007 :: 11:24:
табличноеПоле подтормаживает на местах с дохлой сеткой и замораживает систему во время зачерпывания данных.

Дим, а ты в индекс точно попадаешь?
Или в момент транзакции, выполняемой другими клиентами, тормозит?
  

De quelle planète es-tu?
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #5 - 12. Ноября 2007 :: 13:23
Печать  
kms писал(а) 12. Ноября 2007 :: 13:12:
trdm писал(а) 12. Ноября 2007 :: 11:24:
табличноеПоле подтормаживает на местах с дохлой сеткой и замораживает систему во время зачерпывания данных.

Дим, а ты в индекс точно попадаешь?
Или в момент транзакции, выполняемой другими клиентами, тормозит?

Это было давно на dbf-базе.
Данных было МАЛО. документов 20-30 (тестовая БД), но тормозило/морозило сек на 3-5.
  
Наверх
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #6 - 12. Ноября 2007 :: 13:55
Печать  
trdm писал(а) 12. Ноября 2007 :: 13:23:
Это было давно на dbf-базе.
Данных было МАЛО. документов 20-30 (тестовая БД), но тормозило/морозило сек на 3-5.

ключевое слово - dbf. На SQL таких проблем нет. Значит дело не в ТП, а в провайдере...
  
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #7 - 12. Ноября 2007 :: 13:58
Печать  
Arta писал(а) 12. Ноября 2007 :: 13:55:
trdm писал(а) 12. Ноября 2007 :: 13:23:
Это было давно на dbf-базе.
Данных было МАЛО. документов 20-30 (тестовая БД), но тормозило/морозило сек на 3-5.

ключевое слово - dbf. На SQL таких проблем нет. Значит дело не в ТП, а в провайдере...

Дык в полне возможно. Артем, я тебе эту конфу отправлял. (Обработка.РЕМ_ЖурналРемонта) это она так себя вела. Можешь посмотреть.
  
Наверх
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Многопоточность в 1С
Ответ #8 - 12. Ноября 2007 :: 14:04
Печать  
trdm писал(а) 12. Ноября 2007 :: 13:58:
Дык в полне возможно. Артем, я тебе эту конфу отправлял. (Обработка.РЕМ_ЖурналРемонта) это она так себя вела. Можешь посмотреть.

Я с dbf не баловался - как раз кстати.
Только вспомни, не зря же над oledb провайдером для dbf колдуют Улыбка
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать