Antecedentes:¿Por qué el subproceso win32 no sale automáticamente?
En mi aplicación escrita en C++, que crea un subproceso de trabajo que a su vez crea dos hilos utilizando CreateThread()
. Los dos subprocesos que crea el hilo de trabajo, hable con WCF Service a través de un cliente que se implementa utilizando Windows Web Services API que ofrece la interfaz de programación de aplicaciones C/C++ (API) para crear clientes y servicios web basados en SOAP. Mi aplicación implementa solo el cliente que usa esta API.
Problema:
El problema que estoy enfrentando es que todos los otros hilos salen con gracia, salvo el subproceso de trabajo, como se puede ver a ti mismo, en la siguiente imagen que utiliza WorkerThreadProc
no hay ciclos de CPU, sin embargo, doesn no salir También hay algunos otros subprocesos en ejecución que no son creados por mí, sino por el tiempo de ejecución.
el hilo son los siguientes (según lo informado por ProcessExplorer):
WorkerThreadProc
es en Wait: WrUserRequest estado.wWinMainCRTStartup
está en Espera: UserRequest estado.- Todos
TpCallbackIndependent
están en Esperar: estado de WrQueue.
¿Qué están esperando? ¿Cuáles podrían ser las causas posibles que necesito investigar? Además, ¿cuál es la diferencia entre WrUserRequest y UserRequest? ¿Y qué significa WrQueue? No tengo idea de qué está pasando aquí.
Aquí está mi código WorkerThreadProc. He quitado todas las declaraciones de registro, excepto la última en la parte inferior de la función:
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;
}
Por favor ver la T_VERBOSE
macro, que se utiliza para iniciar la sesión de mensaje detallada. Veo que el mensaje se está registrando, ¡pero el hilo no se cierra!
EDIT:
simplemente les comentaba la siguiente línea en mi WorkerThreadProc
, entonces subproceso de trabajo termina sin novedad!
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
¿Quiere decir que SendMessage
es el culpable? ¿Por qué bloquearía el hilo el hilo de llamada?
¿Estás llamando CloseHandle() en el controlador de subproceso después de que salga? Debería usar WaitForSingleObject() para esperar a que finalice el subproceso. –
@infact: ¡Por supuesto, sí! Y sí, estoy usando 'WaitForSingleObject' para esperar a que termine el hilo. – Nawaz
¿Por qué no usas abstracciones como 'boost :: thread' que funcionan bien (y son incluso portátiles)? – PlasmaHH