Bối cảnh:Tại sao chuỗi win32 không tự động thoát?
Trong ứng dụng của tôi viết bằng C++, tôi tạo ra một sợi công nhân do đó tạo ra hai luồng sử dụng CreateThread()
. Hai luồng mà thread công nhân tạo ra, nói chuyện với WCF Service thông qua một máy khách được thực hiện bằng cách sử dụng Windows Web Services API, cung cấp giao diện lập trình ứng dụng C/C++ (API) để xây dựng các dịch vụ web và khách hàng dựa trên SOAP cho họ. Ứng dụng của tôi triển khai chỉ ứng dụng khách sử dụng API này.
Vấn đề:
Vấn đề tôi đang phải đối mặt là tất cả các chủ đề khác kết thúc tốt đẹp, ngoại trừ các sợi nhân, như bạn có thể nhìn thấy mình, trong hình dưới đây WorkerThreadProc
mà không sử dụng chu kỳ CPU nhưng nó doesn 't thoát. Ngoài ra còn có vài chủ đề khác chạy mà không được tạo ra bởi tôi, nhưng theo thời gian chạy.
Các chủ đề như sau (theo báo cáo của ProcessExplorer):
WorkerThreadProc
là trong Chờ: WrUserRequest nhà nước.wWinMainCRTStartup
đang ở trạng thái Đợi: Trạng thái UserRequest.- Tất cả
TpCallbackIndependent
đang ở trạng thái Chờ: WrQueue.
Họ còn chờ gì nữa? Những nguyên nhân có thể có mà tôi cần phải xem xét là gì? Ngoài ra, sự khác nhau giữa WrUserRequest và UserRequest là gì? Và WrQueue có nghĩa là gì? Tôi hoàn toàn không biết chuyện gì đang diễn ra ở đây.
Đây là mã WorkerThreadProc tôi. Tôi đã gỡ bỏ tất cả các báo cáo khai thác gỗ ngoại trừ người cuối cùng ở dưới cùng của hàm:
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;
}
Hãy xem T_VERBOSE
vĩ mô, nó được sử dụng để đăng nhập thông điệp dài dòng. Tôi thấy thông báo đang được ghi lại, nhưng chuỗi không thoát!
EDIT:
Tôi chỉ nhận xét dòng sau trong tôi WorkerThreadProc
, sau đó sợi nhân thoát duyên dáng!
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
Có nghĩa là SendMessage
là thủ phạm? Tại sao nó sẽ chặn chuỗi chủ đề gọi?
Bạn đang gọi CloseHandle() trên tay cầm chủ đề sau khi nó thoát? Bạn nên sử dụng WaitForSingleObject() để đợi kết thúc. –
@infact: Tất nhiên, có! Và vâng, tôi đang sử dụng 'WaitForSingleObject' để đợi kết thúc! – Nawaz
Tại sao bạn không sử dụng trừu tượng như 'boost :: thread' được chứng minh là hoạt động tốt (và thậm chí là di động)? – PlasmaHH