Справочная информация:
В моем приложении, написанном на C ++, я создаю рабочий поток, который, в свою очередь, создает два потока, используя CreateThread()
. Два потока, которые создает рабочий поток, общаются со Службой WCF через клиента, который реализован с использованием API веб-служб Windows , который предлагает интерфейс программирования приложений C / C ++ (API) для создания веб-служб и клиентов на основе SOAP , Мое приложение реализует только клиент, использующий этот API.
Проблема:
Проблема, с которой я сталкиваюсь, заключается в том, что все остальные потоки завершаются корректно, за исключением рабочего потока, как вы можете видеть на рисунке ниже, что WorkerThreadProc
не использует циклы ЦП, но не завершает работу. Есть также несколько других запущенных потоков, которые созданы не мной, а средой выполнения.
Состояния потоков следующие (как сообщает ProcessExplorer ):
WorkerThreadProc
находится в Ожидание: WrUserRequest состояние.
wWinMainCRTStartup
находится в Ожидание: пользовательский запрос состояние.
- Все
TpCallbackIndependent
находятся в Ожидание: WrQueue состояние.
Чего они ждут? Какие могут быть возможные причины, которые мне нужно изучить? Кроме того, в чем разница между WrUserRequest и UserRequest ? А что означает WrQueue ? Я абсолютно не знаю, что здесь происходит.
![enter image description here](https://i.stack.imgur.com/jdeWJ.png)
Вот мой код 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
, он используется для записи подробного сообщения. Я вижу, что сообщение регистрируется, но поток не завершается!
EDIT:
Я только что прокомментировал следующую строку в моем WorkerThreadProc
, затем рабочий поток завершился изящно!
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
Значит ли это, что SendMessage
является виновником? Зачем ему блокировать поток вызывающего потока?