2011-06-27 20 views
6

Me asomo en el código de mi antepasado y descubrió una fuga en la siguiente situación:Un sueño en el hilo produce pérdida de memoria

1) Lanzamiento de aplicaciones
b) Después de que se puso en marcha la aplicación, cierre la applicaiton plazo de 4 segundos

el mensaje de fugas:

f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {58509} client block at 0x016DFA30, subtype c0, 68 bytes long. 

Posteriormente, pasé por el código, descubrió el punto de causa sospechosa en un 4secs de sueño por la función de control de subproceso de trabajo.

El programa de pruebas:

UINT InitThread(LPVOID pParam) 
{ 
     Sleep(4000); //4000 is the default value, it reads from a registry key. 
     CMyMFCTestProjectDlg* pTest = (CMyMFCTestProjectDlg*)pParam; 
     pTest->DoSomething(); 
     return 0; //--> Exit thread 
} 

BOOL CMyMFCTestProjectDlg::OnInitDialog() { 
... 
AfxBeginThread(InitThread, this); 
... 
} 

Si puedo reducir/eliminar el temporizador de apagado, se resolverá la fuga.
Sin embargo, me gustaría saber cómo sucede. ¿O debido al hilo de trabajo o la terminación del hilo de la GUI? ¿Saldrá el hilo del trabajador después de que el hilo de GUI cause este problema?

¿Alguien puede animar mi día ayudándome a explicar esto? Estoy perdido ...

+0

No es sueño. Necesitas publicar más código. ¿Qué hace el hilo que contiene el sueño? – Matt

+0

@Matt H: hay algunos otros códigos dentro del hilo. Este es un "hilo de dormir" que puede proporcionar la opción de retrasar la ejecución del código restante. Déjame intentar editar el código ... – wengseng

Respuesta

6

Parece que el subproceso de trabajo no tiene la posibilidad de cerrarse correctamente una vez que se cierra la aplicación, ya que el proceso finaliza antes de que finalice. El sistema operativo suele ser bastante bueno para limpiar los recursos por sí mismo, por lo que puede no ser un problema. Sin embargo, es probable que sea mejor si espera a que el hilo salga antes de permitir que la aplicación se apague. Aunque parece que eso causará un retraso de 4 segundos en el cierre de tu aplicación.

Si eso no es aceptable, tendrá que agregar algún mecanismo al hilo, para recibir el evento de cierre del hilo principal de las aplicaciones. Por ejemplo, si sustituye la subprocesos de trabajo de "reposo", con un WaitForSingleObject de un evento:

DWORD res = WaitForSingleObject(
    shutdownEvent, 
    4000); // timeout 
if(res == WAIT_OBJECT_0) 
{ 
    // received the shutdownEvent, exit 
    return 0; 
} 
// The delay has elapsed, continue with rest of thread. 
. . . 

Entonces, cuando su están cerrando en su hilo principal, establece el evento, a continuación, esperar a que el hilo para salir , debe salir casi de inmediato:

SetEvent(this->shutdownEvent); 
WaitForSingleObject(pThread->m_hThread, INFINITE); // pThread is returned from AfxBeginThread 
+0

Cerrar una aplicación generalmente implica llamar a ExitProcess(). Esta API detiene todos los subprocesos en ejecución, excepto la persona que llama, y ​​también lo detiene después de desconectar DLL. No es un requisito abrumador esperar explícitamente a que salgan otros subprocesos de proceso (el sistema operativo no les impedirá ningún problema, independientemente del estado en que se encuentren) bloqueado, inactivo o en ejecución en otra CPU, al sistema operativo no le importa. Muchos problemas de cierre * se causan * al esperar explícitamente a que salgan los subprocesos secundarios, lo que impide que el hilo principal llegue a ExitProcess() y, por lo tanto, cierra la aplicación. –

4

Debe apagar sus hilos correctamente antes de que su proceso desaparezca. Puede hacer que el hilo principal espere a que salga el otro hilo o hacer que el hilo principal indique el otro hilo o hilos para salir.

+0

'Debes cerrar tus hilos correctamente antes de que el proceso desaparezca'. ¿Por qué? El sistema operativo es muy bueno para detener los hilos. Hay muchos casos de problemas de apagado que en realidad son causados ​​por intentos de señalizar los hilos para salir y esperar hasta que lo hayan hecho. Si el subproceso no coopera, (tal vez atascado en alguna API de bloqueo), el hilo principal también permanece atascado y no llega al ExitProcess() que hubiera terminado todos los hilos de todos modos. –

0

68 bytes?

Si la aplicación realmente se apaga, es decir. ha desaparecido del administrador de tareas 'Aplicaciones' y 'Procesos', y el único efecto de esta 'fuga' es emitir un mensaje de depuración al principio, simplemente apague la depuración y olvídese de ella.

Es probable que exista una aberración de cierre de MFC, alguna estructura que no se puede liberar de manera segura durante el apagado y se deja para que el sistema operativo la limpie.

Con el 99.9% de las aplicaciones que no se reinician/detienen continuamente, una fuga de 68 bytes al apagar, incluso si no se limpió, no afectará el funcionamiento de una máquina Windows de manera notable entre el reinicio intervalos aplicados cada 'Martes de parche'.

Estoy seguro de que tienes muchos más errores con efectos más graves que manejar. Si no, ¡puedes tener algo mío!

Rgds, Martin