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

Тема в разделе "MS Visual C++", создана пользователем ivs4, 23 апр 2009.

  1. ivs4

    ivs4 Гость

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Что значит не успевает? Как часто приходят данные в основной поток?
    Ждете до INFINITE или крутится цикл с конкретным интервалом ожидания.
    Без кода тяжело чем-то помочь :D


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

    ivs4 Гость

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

    Код (Text):
    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 , то картина исправляется
    }
    }
     
  4. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Кстати, по поводу "не успевает сбрасываться". Событие с автосбросом сбрасывается ДО возвращения из WaitForSingleObject.

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

    Так чего забивать голову событиями?
     
  5. ivs4

    ivs4 Гость

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

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Т.е. получается, что вы вызываете WaitForSingleObject, передавая ей не объект ядра, а NULL. Думаете это корректный подход? Я не нашел в документации описания поведения в таком случае.
     
  7. ivs4

    ivs4 Гость

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

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

    http://forum.developing.ru/showthread.php?t=12992
     
  8. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Первым делом, я бы отказался от бесконечного ожидания
     
  9. ivs4

    ivs4 Гость

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Вы не правильно меня поняли. Я имел в виду вместо
    Код (Text):
    UINT MyThread(LPVOID pParam){
    while(true){
    dwres=WaitForSingleObject(evNewData,INFINITE);
    if(dwres==WAIT_OBJECT_0){
    //что-то делаю
    }
    }
    }
    использовать:
    Код (Text):
    UINT MyThread(LPVOID pParam){
    while(true){
    dwres=WaitForSingleObject(evNewData,10000);
    if(dwres==WAIT_OBJECT_0){
    //что-то делаю
    }
    else
    {
    // обработка остальных кодов возврата
    }
    }
    }
     
  11. ivs4

    ivs4 Гость

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

    ivs4 Гость

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Такое чувство, что проблема мы не там ищем проблему. Если можете, то сделайте небольшое приложение, иллюстрирующее проблему. Будем разбираться предметно
     
Загрузка...

Поделиться этой страницей