Проблема с SetEvent и WaitForMultipleObjects
От: akatik_jr3  
Дата: 14.04.11 14:21
Оценка:
Добрый день.
У меня в цикле создается поток и я жду, используя WaitForMultipleObjects, что поток либо установить Event0, либо установит Event1, либо пройдет 300мс.
В лог я выдаю результат, который установил поток, и то, что словил WaitForMultipleObjects. Однако периодически эти результаты отличаются. В может быть причина? Код следующий:


typedef struct 
{
    HANDLE resEventUseTrue;  
    HANDLE resEventUseFalse;    //false, если IP не найден и его можно присваивать клиенту.
}
type_sendThread;

static void _sendThread (void* data)
{
    type_sendThread d = *(type_sendThread*)data;

    srand( GetCurrentThreadId () + (unsigned) time (NULL));
    u32 pos =  (rand () % 300);

    _log ("Thread: Sleep %d.", pos);
    Sleep (pos);

    if ((pos / 2) * 2 == pos)
    {
        _log ("Thread: Set use False.");
        SetEvent(d.resEventUseFalse);
    }
    else 
    {
        _log ("Thread: Set use True.");
        SetEvent(d.resEventUseTrue);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    while (1)
    {
    HANDLE hEvents[2];
    hEvents[0] = CreateEvent(NULL, false, false, NULL);
    hEvents[1] = CreateEvent(NULL, false, false, NULL);
    if (hEvents[0] == NULL || hEvents[1] == NULL)
    {
        AERROR ("Main: CreateEvent failed.");
        return true;
    }
    type_sendThread data;
    data.resEventUseTrue = hEvents[0];
    data.resEventUseFalse = hEvents[1];
  
    if (_beginthread (_sendThread, 0, &data) == -1) 
    {
        _log ("Main: _beginthread () failed.");
        return true;
    }

    DWORD res = WaitForMultipleObjects(2, hEvents, false, 300);
    if (res == WAIT_TIMEOUT)
    {
        // Вышли по timeout. 
        _log ("Main:  Timeout.");
    }
    else if (res == WAIT_OBJECT_0)
    {
        // Вышли по sendEvent для resEventTrue. 
        _log ("Main:   Set use True.");
    }
    else if (res == WAIT_OBJECT_0 + 1)
    {
        // Вышли по sendEvent для resEventFalse. 
        _log ("Main:   Set use False.");
    }
    else 
    {
        LOGINTBUG;
    }

    CloseHandle (hEvents[0]);
    CloseHandle (hEvents[1]);
    }

    return 0;
}
Re: Проблема с SetEvent и WaitForMultipleObjects
От: baily Россия  
Дата: 14.04.11 15:21
Оценка:
Здравствуйте, akatik_jr3, Вы писали:

_>Добрый день.

_>У меня в цикле создается поток и я жду, используя WaitForMultipleObjects, что поток либо установить Event0, либо установит Event1, либо пройдет 300мс.
_>В лог я выдаю результат, который установил поток, и то, что словил WaitForMultipleObjects. Однако периодически эти результаты отличаются. В может быть причина? Код следующий:


Ну, если, например, главный поток вылетел по таймауту, то текущий дочерний еще живет на данный момент и может
жить даже тогда, когда главный поток войдет в новую итерацию и создаст новый дочерний поток. Так может повториться несколько раз.
В результате возможно, что у тебя в некоторый момент будет куча потоков. Потом начнутся завершаться дочерние и писать в лог о своих результатах,
которые уже никак не связаны с тем, что напечатает главный поток.
Re: Проблема с SetEvent и WaitForMultipleObjects
От: MShura  
Дата: 14.04.11 20:01
Оценка:
- рабочий поток заснул и у него есть две ячейки памяти d.resEventUseFalse/d.resEventUseTrue
— основной поток отработал timeout
— в тех-же ячейках памяти создал новые event
— запустил другой поток и ему передал те-же две ячейки d.resEventUseFalse/d.resEventUseTrue, но с новыми значениями event'ов
— проснулся первый поток, прочитал из ячеек памяти новые значения, а не те, которые были переданы при старте

Чтобы это увидеть добавьте в лог handle event'ов до Sleep и handle event'ов после Sleep

Решается выделением структуры type_sendThread в куче в функции main и освобождением её при выходе из потока
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.