【发布时间】:2012-02-10 11:33:02
【问题描述】:
背景:
在我用 C++ 编写的应用程序中,我创建了一个工作线程,该工作线程又使用 CreateThread() 创建了两个线程。工作线程创建的两个线程通过客户端与 WCF 服务通信,该客户端使用 Windows Web Services API 实现,该客户端提供 C/C++ 应用程序编程接口 (API),用于构建基于 SOAP 的 Web 服务和客户端。我的应用程序仅使用此 API 实现客户端。
问题:
我面临的问题是所有其他线程都正常退出,除了工作线程,正如您自己看到的那样,在下图中WorkerThreadProc 不使用 CPU 周期但它没有退出。还有一些其他线程不是我创建的,而是运行时创建的。
线程状态如下(ProcessExplorer报道):
-
WorkerThreadProc处于 Wait:WrUserRequest 状态。 -
wWinMainCRTStartup处于 Wait:UserRequest 状态。 - 所有
TpCallbackIndependent都处于Wait:WrQueue状态。
他们还在等什么?我需要调查哪些可能的原因?另外,WrUserRequest 和 UserRequest 有什么区别? WrQueue 是什么意思?我完全不知道这里发生了什么。
这是我的 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 是罪魁祸首?为什么会阻塞调用线程?
【问题讨论】:
-
你是在线程句柄退出后调用 CloseHandle() 吗?您应该使用 WaitForSingleObject() 来等待线程完成。
-
@infact:当然,是的!是的,我正在使用
WaitForSingleObject等待线程完成! -
你为什么不使用像
boost::thread这样被证明可以正常工作(甚至是可移植的)的抽象? -
@PlasmaHH:我不需要便携性。另外,你的意思是win32线程不好(事实证明是这样)?
boost::thread内部使用什么? -
@PlasmaHH:如果我提出有关
boost::thread的问题怎么办?我觉得你的论点很弱。
标签: c++ multithreading wcf web-services