Waitforsingleobject не сбрасывает событие

  • Автор темы ivs4
  • Дата начала
I

ivs4

В основном потоке создается событие с автоматическим сбросом. Запускается дочерний рабочий поток который в вечном цикле ожидает установления события в WaitForSingleObject. Приходящие в основной поток данные устанавливают событие через SetEvent. Но получается так, что один раз проскочив WaitForSingleObject, дочерний поток и в следующий раз его проскакивает, хотя соответствующего SetEvent не было. Такое ощущение, что событие не успевает сбрасываться. Может кто-нибудь встречался с подобной ситуацией?
 
E

European

Такое ощущение, что событие не успевает сбрасываться.
Что значит не успевает? Как часто приходят данные в основной поток?
рабочий поток который в вечном цикле ожидает установления события
Ждете до INFINITE или крутится цикл с конкретным интервалом ожидания.
Может кто-нибудь встречался с подобной ситуацией?
Без кода тяжело чем-то помочь :D


А результат, возвращаемый WaitForSingleObject проверяете?
 
I

ivs4

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

Код:
WinMain(){
...

evNewData=CreateEvent(NULL,FALSE,FALSE,NULL);
if(evNewData==NULL){
return -1;
}
...

//здесь по DDE получаю данные
//на каждую полученную строку вызываю
SetEvent(evNewData)

...
}

UINT MyThread(LPVOID pParam){
while(true){
dwres=WaitForSingleObject(evNewData,INFINITE);
if(dwres==WAIT_OBJECT_0){
//что-то делаю
}
//Если уйти от автоматического сброса и поставить сюда ResetEvent , то картина исправляется
}
}
 
E

European

Такое ощущение, что событие не успевает сбрасываться.
Кстати, по поводу "не успевает сбрасываться". Событие с автосбросом сбрасывается ДО возвращения из WaitForSingleObject.

Далее, из вашего кода не видно, когда создается поток. Кроме того, чтобы избежать возможной взаимной блокировки, я бы ожидал конкретный интервал времени, например, 10 секунд.

я планирую с события перейти на семафор
Так чего забивать голову событиями?
 
I

ivs4

1. По поводу того, что ф-ция сбрасывает состояние события до выхода. Я знаю об этом, но то то и странно, что получается на самом деле. Иначе бы я не обратился за помощью.
2. По поводу временной задержки, не вижу причины для этого. Поток спит пока не взведено состояние, состояние взведено - пошел работать полезный код. Основной поток может уже снова устанавливать событие, чтобы когда дочерний снова встал на WaitForSingleObject, то продолжил работу или не продолжил, если событие не успело взвестись за время работы полезного кода. Просто удивляет, что то же самое работает если уйти от автоматического сброса.
3. Пока я не найду причину такого поведения с событием, я не смогу перейти на семафоры. Причина в том, что семафор работает как раз с автоматическим сбросом. Ситуация повторяется в точности.

Насчет создания дочернего потока, он создается в WinMain до CreateEvent.
 
E

European

Насчет создания дочернего потока, он создается в WinMain до CreateEvent.
Т.е. получается, что вы вызываете WaitForSingleObject, передавая ей не объект ядра, а NULL. Думаете это корректный подход? Я не нашел в документации описания поведения в таком случае.
 
I

ivs4

Извините, я ошибся. Поток создается после CreateEvent.

Вот здесь затронута подобная проблема, правда автор статьи пока не отвечает поборол ли он это или нет

 
E

European

Первым делом, я бы отказался от бесконечного ожидания
 
I

ivs4

была другая схема по приходе данных создавать заново поток и только один. Когда он отработал полезный код, стартуется новый поток. Т.е. всегда должен один поток работать, это добивалось слежением за дескриптором потока, и когда он умирал - создавался новый. Такая схема чревата накладными раходами на выхов ф-ций создания потока, поэтому решил вместо множества следующих друг за другом потоков при старте делать один есдинственный, а данный потом между основным и дочерним потоком разделять через критическую секцию. Такая схеме стала работать заметно шустрее предыдущей. Без вечного цикла мой единственный поток умрет и некому будет делать обрабоку данных. Хотелось как-нибудь реанимировать идею.
 
E

European

Вы не правильно меня поняли. Я имел в виду вместо
Код:
UINT MyThread(LPVOID pParam){
while(true){
dwres=WaitForSingleObject(evNewData,INFINITE);
if(dwres==WAIT_OBJECT_0){
//что-то делаю
}
}
}
использовать:
Код:
UINT MyThread(LPVOID pParam){
while(true){
dwres=WaitForSingleObject(evNewData,10000);
if(dwres==WAIT_OBJECT_0){
//что-то делаю
}
else
{
// обработка остальных кодов возврата
}
}
}
 
I

ivs4

обязательно попробую этот вариант, результатом сразу поделюсь
 
I

ivs4

добрый день. Попробовал предложенный вами вариант - проблема осталась.
 
E

European

Такое чувство, что проблема мы не там ищем проблему. Если можете, то сделайте небольшое приложение, иллюстрирующее проблему. Будем разбираться предметно
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!