2009-02-26 21 views
10

que generará un subproceso utilizando AfxBeginThread que es sólo un bucle while:¿Cómo matar un hilo MFC?

UINT CMyClass::ThreadProc(LPVOID param) 
{ 
    while (TRUE) 
    { 
     // do stuff 
    } 
    return 1; 
} 

¿Cómo matar a este tema en mi destructor de la clase?

creo que algo así como

UINT CMyClass::ThreadProc(LPVOID param) 
{ 
    while (m_bKillThread) 
    { 
     // do stuff 
    } 
    return 1; 
} 

y luego establece m_bKillThread-FALSE en el destructor. Pero todavía tengo que esperar en el destructor hasta que el hilo esté muerto.

Respuesta

19

matar activamente el hilo:

Utiliza el valor de retorno de AfxBeginThread (CWinThread*) para obtener el identificador de hilo (m_hThread) A continuación, pasar de la manilla para la API de Win32 TerminateThread. Sin embargo, esta no es una forma segura de terminar subprocesos, así que por favor sigue leyendo.

Esperando el hilo hasta el final:

Utilice el valor de retorno de AfxBeginThread (CWinThread*) para obtener el miembro m_hThread, a continuación, utilizar WaitForSingleObject(p->m_hThread, INFINITE); Si esta función devuelve WAIT_OBJECT_0, a continuación, el hilo se termina. En lugar de INFINITE, también puede esperar la espera de un milisegundo antes de que se agote el tiempo de espera. En este caso, se devolverá WAIT_TIMEOUT.

de señalización para el hilo que debe terminar:

Antes de hacer la WaitForSingleObject acaba de establecer algún tipo de bandera que el hilo debe salir. Luego, en el ciclo principal del hilo, verificaría ese valor bool y rompería el ciclo infinito. En tu destructor deberías establecer esta bandera y luego hacer un WaitForSingleObject.

aún mejores maneras:

Si usted necesita un mayor control se puede usar algo como boost conditions.

1

Debe esperar, hasta que el hilo haga todas las cosas.

if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0) 
    ;//all right 
else 
    ;//report error 

cuidado con la función TerminateThread, esto es muy peligroso.

4

BTW, Acerca de TerminateThread(), úsela de esta manera.

DWORD exit_code= NULL; 
if (thread != NULL) 
{ 
    GetExitCodeThread(thread->m_hThread, &exit_code); 
    if(exit_code == STILL_ACTIVE) 
    { 
     ::TerminateThread(thread->m_hThread, 0); 
     CloseHandle(thread->m_hThread); 
    } 
    thread->m_hThread = NULL; 
    thread = NULL; 
} 
1

En primer lugar usted tiene que comenzar el hilo de una manera tan MFC no se elimina el objeto hilo cuando es finished, la configuración predeterminada para el hilo de MFC es borrarse a sí mismo por lo que desea apagar eso.

m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED); 
    m_thread->m_bAutoDelete = FALSE; 
    m_thread->ResumeThread(); 

Ahora en el hilo, desea un mecanismo que el hilo de la persona que llama puede enviar una señal para que se termine. Hay varias maneras, una es la WaitForSingleObject para verificar el estado de la señal u otra forma es simplemente enviar a este hilo un mensaje para que termine. Esto es un final elegante que lo mata.

Mientras que este subproceso se está terminando (= saliendo de la función de subproceso, limpiando), puede hacer que el subproceso principal espere para finalizar antes de que finalice.

 int wait = 2000 // seconds (I am waiting for 2 seconds for worker to finish) 
    int dwRes = WaitForSingleObject(m_thread->m_hThread, wait); 
    switch (dwRes) 
    { 
    case WAIT_OBJECT_0: 
     TRACE(_T("worker thread just finished")); break; 
    case WAIT_TIMEOUT: 
     TRACE(_T("timed out, worker thread is still busy")); break; 
    } 

ajuste de la nota anterior m_bAutoDelete = FALSE hecho posible que todavía tienen un identificador válido cuando el hilo termina por lo que podemos esperar en él. Lo último que desea hacer ahora es eliminar el objeto CWinThread para liberar su memoria (ya que asumimos la responsabilidad de hacerlo).