Почему поток win32 не завершается автоматически?

Предпосылки:

В моем приложении, написанном на C ++, я создаю рабочий поток, который, в свою очередь, создает два потока с помощью CreateThread () . Два потока, которые создает рабочий поток, взаимодействуют со службой WCF через клиента, который реализован с использованием API веб-служб Windows , который предлагает интерфейс прикладного программирования (API) C / C ++ для создания веб-служб на основе SOAP и клиентов для них. . Мое приложение реализует только клиента, использующего этот API.

Проблема:

Проблема, с которой я столкнулся, заключается в том, что все другие потоки завершаются корректно, за исключением рабочего потока, как вы сами видите на изображении ниже, что WorkerThreadProc еще не использует циклов ЦП это не выходит. Есть также несколько других запущенных потоков, которые созданы не мной, а средой выполнения.

Состояния потоков следующие (как сообщает ProcessExplorer ):

  • WorkerThreadProc находится в Wait: WrUserRequest состоянии.
  • wWinMainCRTStartup находится в состоянии Ожидание: UserRequest .
  • Все TpCallbackIndependent находятся в состоянии Ожидание: WrQueue .

Чего они ждут? Какие могут быть возможные причины, которые мне нужно изучить? Кроме того, в чем разница между WrUserRequest и UserRequest ? А что означает WrQueue ? Я совершенно не понимаю, что здесь происходит.

enter image description here


Вот мой код WorkerThreadProc. Я удалил все операторы ведения журнала, кроме последнего в нижней части функции:

DWORD WINAPI WorkerThreadProc(PVOID pVoid)
{

    //Initialize GDI+
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR           gdiplusToken;

    Status status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    if ( status != Status::Ok )
    {
        return 1;
    }

    GuiThreadData *pGuiData = (GuiThreadData*)pVoid;

    auto patternIdRequestQueue= new PatternIdRequestQueue();
    auto resultQueue = new ResultQueue();

    auto patternManager = new PatternManager(patternIdRequestQueue);
    LocalScheduler *pScheduler = new LocalScheduler(resultQueue, patternManager);

    bool bInitializationDone = pScheduler->Initialize(pGuiData->m_lpCmdLine);
    if ( !bInitializationDone )
    {
        return 0;
    }

    //PatternIdThread
    PatternIdThread patternIdThread(patternIdRequestQueue);
    DWORD dwPatternIdThreadId;
    HANDLE hPatternIdThread = CreateThread(NULL, 0, PatternIdThreadProc, &patternIdThread, 0, &dwPatternIdThreadId);

    ResultPersistence resultPersistence(resultQueue);
    DWORD dwResultPersistenceThreadId;
    HANDLE hResultPersistenceThread = CreateThread(NULL, 0, ResultPersistenceThreadProc, &resultPersistence, 0, &dwResultPersistenceThreadId);

    pScheduler->ScheduleWork(pGuiData->m_hWnd, pGuiData->m_hInstance, ss.str());

    pScheduler->WaitTillDone();
    patternIdThread.Close();
    resultPersistence.Close();

    delete pScheduler; 

    //Uninitialize GDI+
    GdiplusShutdown(gdiplusToken);

    dwRet = WaitForSingleObject(hPatternIdThread, INFINITE);
    CloseHandle(hPatternIdThread);

    dwRet = WaitForSingleObject(hResultPersistenceThread,INFINITE);
    CloseHandle(hResultPersistenceThread);

    SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);

    //IMPORTANT : this verbose message is getting logged!
    T_VERBOSE(EvtSrcInsightAnalysis, 0, 0, "After sending message to destroy window");

    delete patternManager;
    delete patternIdRequestQueue;
    delete resultQueue;
    return 0;
}

См. Макрос T_VERBOSE , он используется для записи подробного сообщения. Я вижу, что сообщение регистрируется, но поток не завершается!


РЕДАКТИРОВАТЬ:

Я только что прокомментировал следующую строку в моем WorkerThreadProc , затем рабочий поток завершается корректно!

SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);

Означает ли это, что SendMessage является виновником? Зачем ему блокировать поток вызывающий поток?

6
задан Nawaz 10 February 2012 в 13:43
поделиться