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

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

ivs4

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


А результат, возвращаемый WaitForSingleObject проверяете?
 
Спасибо за отклик.
Бывает не часто, но бывает :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 , то картина исправляется
}
}
 
Такое ощущение, что событие не успевает сбрасываться.
Кстати, по поводу "не успевает сбрасываться". Событие с автосбросом сбрасывается ДО возвращения из WaitForSingleObject.

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

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

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

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

 
Первым делом, я бы отказался от бесконечного ожидания
 
была другая схема по приходе данных создавать заново поток и только один. Когда он отработал полезный код, стартуется новый поток. Т.е. всегда должен один поток работать, это добивалось слежением за дескриптором потока, и когда он умирал - создавался новый. Такая схема чревата накладными раходами на выхов ф-ций создания потока, поэтому решил вместо множества следующих друг за другом потоков при старте делать один есдинственный, а данный потом между основным и дочерним потоком разделять через критическую секцию. Такая схеме стала работать заметно шустрее предыдущей. Без вечного цикла мой единственный поток умрет и некому будет делать обрабоку данных. Хотелось как-нибудь реанимировать идею.
 
Вы не правильно меня поняли. Я имел в виду вместо
Код:
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
{
// обработка остальных кодов возврата
}
}
}
 
обязательно попробую этот вариант, результатом сразу поделюсь
 
добрый день. Попробовал предложенный вами вариант - проблема осталась.
 
Такое чувство, что проблема мы не там ищем проблему. Если можете, то сделайте небольшое приложение, иллюстрирующее проблему. Будем разбираться предметно
 
Мы в соцсетях:

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