Mutex.SignalEvent
| SignalEvent (Работа с событиями) | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||
Функция меняет состояние текущего события на установлено.
Синтаксис
Mutex.SignalEvent()
Примеры
//Пример показывает простой способ синхронизации между двумя потоками, первый поток получает внешние запросы, а второй поток обрабатывает их,
// и передает ответ назад в первый поток, который пересылает ответ во внешний источник
//Использование событий позволяет выполнить запрос без каких либо пауз (какие появлялись бы при использовании функции Sleep внутри цикла)
//Пример использует 3 события:
// * собВнешниеДанныеПоступили -- событие устанавливается в момент поступления внешних данных (механизм здесь не показан, он может быть любым -- событие TCP или внешнее устройство)
// * собЗапросНаОбработку -- событие, которое устанавливает первый поток, когда он получил новые внешние данные и требуется передать их второму потоку на работку
// второй поток находится в ожидании этого события
// * собДанныеОбработаны -- событие, которое устанавливает второй поток, когда он обработал данные, полученные от первого потока
//Фрагмент инициализации, происходящий до рабочего цикла
собВнешниеДанныеПоступили:=Mutex.CreateEvent();
собЗапросНаОбработку:=Mutex.CreateEvent();
собДанныеОбработаны:=Mutex.CreateEvent();
//Очереди данных и обработанных данных
спДанные:=List.Create();
спРезультат:=List.Create();
SetMultiThreaded(спДанные);
SetMultiThreaded(спРезультат);
aList:=List.Create();
aList.SetByName("ЗапросНаОбработку",собЗапросНаОбработку);
aList.SetByName("ДанныеОбработаны",собДанныеОбработаны);
aList.SetByName("Данные",спДанные);
aList.SetByName("Результат",спРезультат);
//Модуль не будет иметь формы, будет выполняться в фоне
LoadModule(0,"Modules\FreeForms\СпециальныеОбработки\ОбработчикСобытий",aList,,"Module","Form");
...
спСобытия:=List.Create(собВнешниеДанныеПоступили,собДанныеОбработаны);
//Основной цикл обработки данных
While 1 Do
//Другая работа в цикле, проверка условия выхода из цикла и окончания работы
...
//Ожидание получения или отсылки
aNum:=Mutex.WaitForEvents(спСобытия,250);
If aNum=1 Then
//Поступили данные из внешнего источника, получим данные
//Возможно здесь необходимо проверить количество данных в очереди (спДанные.Size()) и, при переполнении, отказать в получении этих данных
аДанные:=...
LockObject(спДанные);
Try
//Добавим данные в список данных, использование LockObject здесь не обязательно, однако, если кроме Add, будут использоваться
// другие функции для работы с спДанные, LockObject будет необходим. LockObject здесь использован для универсальности примера.
спДанные.Add(аДанные);
Finally
UnlockObject(спДанные);
EndTry;
//Сигнал второму потоку о наличии данных
собЗапросНаОбработку.SignalEvent();
ElseIf aNum=2 Then
While спРезультат.Size()>0 Do
LockObject(спРезультат);
Try
//Использование LockObject здесь не обязательно, так как другой поток только добавляет данные в спРезультат в конец списка.
// LockObject здесь использован для универсальности примера.
аРезультат:=спРезультат.Get(1);
спРезультат.Remove(1);
Finally
UnlockObject(спРезультат);
EndTry;
//Осуществим отправку данных аРезультат
...
EndDo;
EndIf;
EndDo;
//Данный кусок кода располагается в обработке Modules\FreeForms\СпециальныеОбработки\ОбработчикСобытий
Function OnOpen()
Result:=0;
If TypeStr(Param)<>"LIST" Then
Exit;
EndIf;
собЗапросНаОбработку:=aList.GetByName("ЗапросНаОбработку");
собДанныеОбработаны:=aList.GetByName("ДанныеОбработаны");
спДанные:=aList.GetByName("Данные");
спРезультат:=aList.GetByName("Результат");
//Основной цикл обработки данных
While 1 Do
//Проверка на окончание работы
...
If собЗапросНаОбработку.WaitForEvent(250)=1 Then
While спДанные.Size()>0 Do
LockObject(спДанные);
Try
//Использование LockObject здесь не обязательно, так как другой поток только добавляет данные в спДанные в конец списка.
// LockObject здесь использован для универсальности примера.
аДанные:=спДанные.Get(1);
спДанные.Remove(1);
Finally
UnlockObject(спДанные);
EndTry;
//Обработаем данные аДанные и создадим результат аРезультат
...
//Добавим результат в очередь результатов
LockObject(спРезультат);
Try
//Использование LockObject здесь не обязательно, так как единственная функция Add имеет свой механизм блокирования.
// LockObject здесь использован для универсальности примера.
спРезультат.Add(аРезультат);
Finally
UnlockObject(спРезультат);
EndTry;
//Сообщим первому потоку, что появился новый результат
собДанныеОбработаны.SignalEvent();
EndDo;
EndIf;
EndDo;
EndFunction