Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > deadlock при использовании ReplyMessage


Автор: 0xDEAD 11.8.2012, 11:18
Добрый день!

Есть у меня такой код:

Код

LRESULT CALLBACK Proc(/*...*/)
{
    switch(uMsg)
    {
    //...

    case MSG_EVENTBLOCK:
        ReplyMessage(0);
        WaitForSingleObject((HANDLE)wParam, INFINITE);
        break;

    //...
    }

    return /*...*/;
}


Код

BOOL Function(/*...*/)
{
    HANDLE hEvent;

    hEvent = CreateEvent(/*...*/);

    // ...

    SendMessage(hWnd, MSG_EVENTBLOCK, (WPARAM)hEvent, 0);

    //...

    SetEvent(hEvent);
    CloseHandle(hEvent);

    return /*...*/;
}


Окошко и функция запускаются в разных потоках.
По задумке, функция Function должна заморозить поток окошка, сделать свою работу, и снова его отморозить.
Это почти всегда работает, но иногда зависает: Function не возвращается с SendMessage (строка 9), несмотря на то, что Proc вызвал ReplyMessage!

Как такое получается?

Автор: bass 11.8.2012, 14:01
SendMessage ждет обработки сообщения..... А поток оконной процедуры как вы пишите замораживаеться.... Ну и дид лок......
Посмотрите в сторону PostMessage 

Автор: 0xDEAD 11.8.2012, 14:37
Цитата(bass @  11.8.2012,  14:01 Найти цитируемый пост)
SendMessage ждет обработки сообщения

Так я же вызываю ReplyMessage, не должен он ждать.
Опять же, обычно все правильно работает, но иногда зависает.

Цитата(bass @  11.8.2012,  14:01 Найти цитируемый пост)
Посмотрите в сторону PostMessage  

А что туда смотреть? Единственный вариант, который мне пришел в голову, это использовать два события:

Код

LRESULT CALLBACK Proc(/*...*/)
{
    switch(uMsg)
    {
    //...
    case MSG_EVENTBLOCK:
        SetEvent((HANDLE)lParam);
        WaitForSingleObject((HANDLE)wParam, INFINITE);
        break;
    //...
    }
    return /*...*/;
}


Код

BOOL Function(/*...*/)
{
    HANDLE hEvent, hWaitEvent;

    hEvent = CreateEvent(/*...*/);
    hWaitEvent= CreateEvent(/*...*/);

    PostMessage(hWnd, MSG_EVENTBLOCK, (WPARAM)hEvent, (LPARAM)hWaitEvent);
    WaitForSingleObject(hWaitEvent, INFINITE);
    SetEvent(hWaitEvent);

    //...

    SetEvent(hEvent);
    CloseHandle(hEvent);

    return /*...*/;
}

Автор: korian 11.8.2012, 15:35
Поток с Function только один?
А вообще посмотрите и дайте посмотреть стеки потоков при дедлоке.

Автор: 0xDEAD 11.8.2012, 15:39
Цитата(korian @  11.8.2012,  15:35 Найти цитируемый пост)
Поток с Function только один?

Да

Цитата(korian @  11.8.2012,  15:35 Найти цитируемый пост)
А вообще посмотрите и дайте посмотреть стеки потоков при дедлоке.

Proc: функция WaitForSingleObject (строка 9).
Function: функция SendMessage (строка 9).

Автор: korian 11.8.2012, 16:04
ну у меня только один вариант, когда вызывается SendMessage в Function, основной поток уже висит на WaitForSingleObject.
Можно проверить:
Надо какой-нить третий поток, которым можно будет управлять из debugera
1) Ловим deadlock,
2) замораживаем Function поток
3) в вспомогательном потоке размораживаем основной поток (отпускаем объект для WaitForSingleObject в основном потоке)
4) если в основном потоке опять появится сообщение MSG_EVENTBLOCK, то где-то косяк в логике

Автор: GremlinProg 13.8.2012, 07:00
Цитата(korian @  11.8.2012,  18:04 Найти цитируемый пост)
где-то косяк в логике

 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)