2012-03-15 16 views
5

Estoy comenzando un hilo usando AfxBeginThread. Esto devuelve un puntero a un nuevo objeto CWinThread.¿A quién pertenece CWinThread después de haber sido creado por AfxBeginThread?

MSDN indica que este puntero es NULO y desasignará todo si falla la creación. Sin embargo, tan pronto como el hilo sale después de comenzar regularmente, el objeto CWinThread aún existe. No estoy seguro de si debería eliminar el objeto CWinThread o si esto lo hace MFC (aunque no parece).

FYI no es probable que el hilo salga, ya que debe ejecutarse hasta que finalice la aplicación. Sin embargo, dado que lo uso para formar parte de un grupo de subprocesos, no quiero que el CWinThread cuelgue de una vez por todas.

Respuesta

2

Si el hilo todavía se está ejecutando, no debe eliminarlo. Una vez que se haya detenido, sólo tiene que utilizar el operador delete en el puntero devuelto por AfxBeginThread con el fin de liberar la memoria utilizada por el hilo:

CWinThread *thread = AfxBeginThread(...); 
/* ... */ 
// now wait for it to terminate 
WaitForSingleObject(thread->m_hThread, INFINITE); 
delete thread; 

debe almacenar el CWinThread punteros hasta que los extremos del hilo/aplicación, para que pueda liberar la memoria asignada para ellos. De lo contrario, tendrá una pérdida de memoria.

+4

Esta respuesta es incorrecta. Al finalizar el hilo, 'CWinThread' cerrará el manejador del hilo y se eliminará. Por lo tanto, este código puede llamar a 'WaitForSingleObject' en un identificador cerrado, que es un comportamiento indefinido, o puede intentar eliminar un objeto que ya ha sido eliminado. El enfoque correcto es usar 'm_bAutoDelete' en un hilo _suspended_, como se explica en una respuesta de @jla. –

4

Nunca confié en CWinThread para limpiar después de sí mismo. Por lo general crear hilos y yo digo MFC que voy a hacer la limpieza, especialmente cuando el programa se está cerrando:

CWinThread *thread = AfxBeginThread(...); 
thread->m_bAutoDelete = FALSE; 

Usted, sin embargo, tiene que guardar el puntero del hilo de lo contrario va a tener pérdidas de memoria.

+0

gracias, acabo de enterarme del miembro m_bAutoDelete y lo hago como usted y @fontanini sugieren. +1 – Alex

+3

Esta respuesta es incorrecta. Para cuando este código intenta establecer 'm_bAutoDelete', el objeto' CWinThread' ya puede haberse borrado. Vea la respuesta de @jla sobre cómo usar esta técnica correctamente. –

+0

No estoy de acuerdo con que la respuesta sea incorrecta. La clave de la respuesta es m_bAutoDelete, y los parámetros de la muestra son "..." omitidos por brevedad. También es imprescindible que CREATE_SUSPENDED; de lo contrario, tu comentario es correcto. Estoy de acuerdo en que la respuesta de @jila es más completa. –

7

La responsabilidad de limpiar el objeto CWinThread depende de su valor m_bAutoDelete. El valor predeterminado es eliminarse a sí mismo. Para disparar y olvidar los hilos de ejecución corta esto está bien. Se limpiará después de sí mismo.

Si su thread es de larga ejecución y necesita ser avisado de que es hora de salir o interactuar con él, querrá que el identificador CWinThread siga siendo válido y no apunte a un objeto autoadministrado.

Si establece m_bAutoDelete en FALSE, se responsabiliza de eliminarlo. Para ir a lo seguro con el puntero devuelto, debes crear suspendido y establecerlo en FALSE antes de reanudarlo, tal como sugirió Joseph Newcomer en su artículo Using Worker Threads.

thread = AfxBeginThread(proc, this, 
         THREAD_PRIORITY_NORMAL, // default: use it 
         0,  // default stack size 
         CREATE_SUSPENDED); // let us set auto delete 
    if(thread) { // protect against that rare NULL return 
     thread->m_bAutoDelete = FALSE; 
     thread->ResumeThread(); 
    } 
+2

Esta es la única respuesta correcta. Las otras dos respuestas son incorrectas y pueden causar un comportamiento indefinido. –

+0

Si tiene un hilo de la GUI con m_bAutoDelete = TRUE y observa que el hilo no sale aunque el usuario hizo clic en el botón "Cerrar" de la ventana principal, puede ser necesario llamar a PostQuitMessage() en PostNcDestroy(). – Elmue

+1

Tenga en cuenta también que si está limpiando después del hilo usted mismo (m_bAutoDelete = FALSE), igual querrá esperar a que el hilo salga antes de eliminar el objeto – Luis

Cuestiones relacionadas