Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.02.02;
Скачать: [xml.tar.bz2];

Вниз

Объясните мне, как работать с WaitForMultipleObjects?   Найти похожие ветки 

 
Aleksandr   (2003-11-04 11:33) [0]

Как создать указатель на массив эвентов, чего там за комментарий в хнлпе по поводу акцесса в Виндх НТ - ничего не понимаю :)


 
Digitman   (2003-11-04 12:55) [1]


> Как создать указатель на массив


обычным для Паскаля образом. Ивенты там будут или не ивенты - индифферентно.


> чего там за комментарий в хнлпе по поводу акцесса в Виндх
> НТ - ничего не понимаю


Ивенты, хэндлы которыех будут помещены тобой в массив перед передачей адреса массива параметром в ф-цию, должны быть созданы с флагом-спецификатором доступа к ним SYNCHRONIZE.


 
Aleksandr   (2003-11-04 14:23) [2]

Спасибо, что объяснили. А не могли бы Вы заодно и рассказать, как создать этот флаг-спецификатор? Насколько я понимаю, он должен быть в первом параметре CreateEvent?


 
Digitman   (2003-11-04 14:42) [3]

нет.

CreateEvent создает ивент с правами EVENT_ALL_ACCESS

т.е поток (A), создавший ивент, имеет на него все возможные права

а вот тот код.поток (B), который выполнил OpenEvent (дабы воспользоваться этим существующим ивентом), должен указать комбинацию флагов-спецификаторов.

если (B) хочет только синхронизироваться с сигналами ивента (см. WaitFor-ф-ции), он должен уcтановить флаг прав на синхронизацию


 
Aleksandr   (2003-11-04 15:22) [4]

Запутался. У меня один поток создает эвенты и передает их другим потокам (по одному на каждого), а затем дожидается, пока эвенты не будут установлены.
Что до получивших эвенты потоков, то они просто выполняют SetEvent(qHandle). Надо ли им что-то открывать и устанавливать какие-то права?


 
Aleksandr   (2003-11-05 15:00) [5]

Млин, ну вообще не понимаю, в чем дело. Если делаю только один эвент, то SetEvent делается, если жду хотя бы двух - то таймауты:


var
FHArr : TWOHandleArray;
i : integer;
DExt : longint;
WaitRes : cardinal;
begin
for i:=0 to length(FHArr)-1 do
FHArr[i]:=0; // fill events array by 0
for i:=0 to EtQ.Count-1 do begin // etQ - list of objects
FHArr[i]:=CreateEvent(nil, True, False,PChar(IntToHex(EtQ.Items[i].ID,4)+IntToStr(EtQ.Items[i].qID)));
EtQ.Items[i].qHandle:=FHArr[i]
end;
try
DExt:=0;
i:=EtQ.Count;
QueryManager.ProcessQuery(EtQ); //manager of threads, wich sets events
repeat
WaitR:=WaitForMultipleObjects(i,@FHArr,True,30000);
if WaitR=WAIT_OBJECT_0 then
Break;
ContinueSession;
Inc(DExT, ContSesRefreshInterval);
Sleep(50)
until (WaitR=WAIT_OBJECT_0) OR (WaitR=WAIT_ABANDONED) OR (WaitR= WAIT_FAILED) OR (DExT>TimeToProcessQuery);
...


 
Digitman   (2003-11-05 15:53) [6]

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

Судя по коду - последнее

bWaitAll

Specifies the wait type. If TRUE, the function returns when the state all objects in the lpHandles array is signaled. If FALSE, the function returns when the state of any one of the objects set to is signaled. In the latter case, the return value indicates the object whose state caused the function to return.


 
Aleksandr   (2003-11-05 16:56) [7]

Мне нужен момент, когда все отсигналят. bWaitAll=true. Но вот какие-то проблемы с этим творятся. Только что без всякой перекомпиляции отработали все объекты. А при запуске до этого не отработал ни один. Причем с обоими вариантами (в потоках, устанавливающих событие):

1. SetEvent(FEv.qHandle)
2. H:=OpenEvent(EVENT_ALL_ACCESS,true,PChar(IntToHex(FEv.ID,4)+IntToStr(FEv.qID)));
if H>0 then
SetEvent(H)


 
Aleksandr   (2003-11-06 12:44) [8]

Млин... И вообще, OpenEvent почему-то совсем другой handle возвращает, по данному имени.


 
Aleksandr   (2003-11-06 16:34) [9]

Истчо один прикол не могу понять - при использовании WaitForMultipleObjects почему-то резко утормаживает всю программу (хотя находится в отдельном потоке).


 
Digitman   (2003-11-06 16:49) [10]

при использовании ивента в контексте одного и того же процесса нет необходимости использовать OpenEvent(), ибо полученный хэндл ивента, созданного при CreateEvent() одним код.потоком, может быть им (потоком-создателем) с легкостью передан другому код.потоку для использования

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


> И вообще, OpenEvent почему-то совсем другой handle возвращает,
> по данному имени.


ну и что ? так и должно быть


> при использовании WaitForMultipleObjects почему-то резко
> утормаживает всю программу


что есть "программа" ? если ты о визуальном "торможении" обновления окон VCL-приложения, то есть прямой резон говорить об основном кодовом потоке процесса ... а "программа" - штука абстрактная и неощутимая))


 
Aleksandr   (2003-11-06 16:56) [11]

Спасибо, понял.

> что есть "программа"
Ну, я имел в виду, что остальные потоки в программе резко замедляют свою работу на период его ожидания эвентов.


 
Digitman   (2003-11-06 17:35) [12]

когда код.поток вызвал одну из ф-ций ожидания объектов синхронизации (ОС) (неважно, ивент этот ОС или иной), он вообще не "работает", он "спит", система не выделяет ему кванты времени.

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


 
Sapersky   (2003-11-26 15:12) [13]

Вот, может, заодно мне объясните - можно ли проверять ситуацию, когда сигналит хотя бы одно событие, но если отсигналили несколько - получить номер КАЖДОГО отсигналившего. WaitForMultipleObjects возвращает номер только одного.


 
clickmaker   (2003-11-26 15:15) [14]


> Sapersky © (26.11.03 15:12) [13]
> если отсигналили
> несколько - получить номер КАЖДОГО отсигналившего. WaitForMultipleObjects
> возвращает номер только одного

Кто раньше отсигналил, того и возвращает


 
Reindeer Moss Eater   (2003-11-26 16:04) [15]

WaitForMultipleObjects возвращает номер только одного.

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


 
Digitman   (2003-11-26 16:04) [16]


> Sapersky


см.
> clickmaker © (26.11.03 15:15) [14]


точно) ... "Кто первый встал - того и тапки" (с)

описание результата ф-ции :

WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount - 1)

If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.


 
Sapersky   (2003-11-26 16:44) [17]

Извиняюсь, некорректно сформулировал. Я как раз этот фрагмент и имел в виду:

If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.

А мне нужен не smallest, а номера ВСЕХ, которые became signalled during the call.


 
MBo   (2003-11-26 16:50) [18]

>Sapersky
WaitForSingleObject для каждого, как RME написал


 
clickmaker   (2003-11-26 16:52) [19]

Пройдись по ним в цикле WaitForSingleObject с нулевой задержкой после того, как они отсигналили и узнаешь состояние каждого


 
Digitman   (2003-11-26 17:00) [20]


> Sapersky


проблем-то - никаких !

ты ж в цикле вызываешь WaitForMultipleObjects() ?

всякий раз, когда "просигналит" очер.ивент из массива, ты можешь либо сбросить его тут же явно (ResetEvent) либо он неявно сбрасывается (если был создан с ManualReset = False), и при следующей итерайии цикла мешать он тебе уже не будет


 
Sapersky   (2003-11-26 17:20) [21]

И правда, если вручную резетить, можно получить все... Спасибо.


 
MBo   (2003-11-26 17:20) [22]

Кстати, у Рихтера в 10 главе, если я правильно помню, есть что-то похожее на твои требования



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.02.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.009 c
14-2295
Calm
2004-01-11 14:31
2004.02.02
Посоветуйте прогу, расширяющую возможности буфера обмена.


1-2082
Dion
2004-01-15 09:06
2004.02.02
Доступ к папке (+)


4-2412
Aalexis
2003-11-21 13:34
2004.02.02
Дата создания файла и использование структуры FileTime.


3-2030
Паша_
2004-01-05 23:22
2004.02.02
Внутренности Alias


1-2208
DmitryA
2004-01-20 17:12
2004.02.02
ScrollBar в ComboBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский