Difference between revisions of "Mutex.WaitForEvent"
(Created page with "{{infobox function |name=WaitForEvent |object=Семафор |caption=Цикл ожидани...") |
m (1 revision imported) |
(No difference)
|
Latest revision as of 07:51, 7 February 2021
WaitForEvent (Цикл ожидания) | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Функция выполняет цикл ожидания для текущего события в течение указанного времени (по умолчанию, время не ограничено). Если событие произошло (было установлено функцией SignalEvent), функция возвращает 1 и автоматически сбрасывает состояние события. Во время исполнения цикла ожидания, обрабатываются внешние события, цикл ожидания также можно прервать из визуального клиента.
Синтаксис
Mutex.WaitForEvent(<Время ожидания в мс. (INT)>=-1):<0, если время закончилось, 1, если произошло событие (INT)>
Аргументы
<Время ожидания в мс. (INT)>
- (необязательный аргумент) Задает время ожидания установки текущего события, функция возвращается либо, когда событие будет установлено, либо, когда истечет время ожидания. При указании -1, время ожидания не ограничено.
Возвращаемое значение
Возвращает 0, если истекло время ожидания, 1, если за время ожидания событие было установлено.
Примеры
//Пример показывает простой способ синхронизации между двумя потоками, первый поток получает внешние запросы, а второй поток обрабатывает их, // и передает ответ назад в первый поток, который пересылает ответ во внешний источник //Использование событий позволяет выполнить запрос без каких либо пауз (какие появлялись бы при использовании функции 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