Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Почему зависает выполнение?


Автор: xTr1m 21.3.2011, 19:20
Доброго времени суток. Есть код (запускается два потока и ожидается их выполнение) :

Код

const int size = 800;

UINT Func1( LPVOID pParam )
{
    for(int i=0; i<size; ++i)
    {
        for(int j=0; j<size; ++j)
        {
            for(int m=0; m<size; ++m)
            {
                int h = 0;
            }
        }
    }
    
    //AfxMessageBox("Complete 1");
    return 0;
}

UINT Func2( LPVOID pParam )
{
    for(int i=0; i<size; ++i)
    {
        for(int j=0; j<size; ++j)
        {
            for(int m=0; m<size; ++m)
            {
                int h = 0;
            }
        }
    }
    
    //AfxMessageBox("Complete 2");
    return 0;
}

void CmultiprocDlg::OnBnClickedButton1()
{
    CWinThread *pThread1 = AfxBeginThread(Func1, this);
    CWinThread *pThread2 = AfxBeginThread(Func2, this);

    HANDLE arr[2];
    arr[0] = pThread1->m_hThread;
    arr[1] = pThread2->m_hThread;

    WaitForMultipleObjects(2, &arr[0], true, INFINITE);        
    AfxMessageBox(_T("finished"));
}


Этот код работает. Но если раскомментировать строки с AfxMessageBox, то все зависает. То есть, когда доходит до сообщения в первом потоке (ставлю там breakpoint), дальше жму F10 и все наглухо повисает. В чем проблема? AfxMessageBox какой то потокобезопасный и чего то ждет? Спасибо.

Автор: Albor 22.3.2011, 08:36
Осмелюсь предположить, что MessageBox появляется, но невидим, а, поскольку это модальное окно, создаётся эффект зависания.

Автор: xTr1m 22.3.2011, 09:40
Штука получается такая, что если убрать WaitForMultipleObjects, то сообщения появляются.

Автор: Albor 22.3.2011, 10:37
Эта строчка ожидает сигналы от обоих потоков бесконечно, а чтобы функция потока завершилась, нужно завершить работу MessageBox-a. 

Автор: xTr1m 22.3.2011, 10:53
Ага, ну примерно стало ясно. Неясно другое - почему messagebox не отображается =)

Автор: Albor 22.3.2011, 11:55
Вот из MSDN
Цитата

Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjects.

То есть нужно использовать MsgWaitForMultipleObjects или MsgWaitForMultipleObjectsEx, так как функция потока создаёт окно.

Автор: xTr1m 22.3.2011, 13:30
Вау, огромное спасибо. Даже не знаю как вы это нашли =)

Автор: Albor 22.3.2011, 14:14
Цитата(xTr1m @  22.3.2011,  12:30 Найти цитируемый пост)
 Даже не знаю как вы это нашли =) 

Да это не мудрено. В описании функций есть ремарки, там это и описывается.

Автор: Dem_max 23.3.2011, 11:02
нельзя MessageBox вызывать в потоке, их нужно вызывать в основном потоке обработки сообщений путем. 

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