c winapi pthreads exit main

c - ¿Está bien llamar a pthread_exit desde main?



winapi pthreads (3)

Cuando llamo pthread_exit desde main , el programa nunca llega a terminar. Esperaba que el programa terminara, ya que estaba saliendo del único hilo del programa, pero no funciona. Parece colgado.

#include <stdio.h> #include <stdlib.h> #include <pthread.h> int main(int argc, char *argv[]) { printf("-one-/n"); pthread_exit(NULL); printf("-two-/n"); }

Process Explorer muestra que el subproceso (único) está en el estado Wait:DelayExecution .

De acuerdo con la documentación de pthread_exit :

El proceso debe salir con un estado de salida de 0 después de que se haya terminado el último subproceso. El comportamiento será como si la implementación llamara a exit () con un argumento cero en el tiempo de finalización del subproceso.

Estoy usando Dev-C ++ v4.9.9.2 y pthreads-win32 v2.8.0.0 (vinculando contra libpthreadGC2.a ).

La biblioteca parece estar bien (por ejemplo, llamar pthread_self o pthread_create desde main funciona bien).

¿Hay alguna razón para lo que se supone que no debo llamar a pthread_exit desde main ?


Bueno, es definitivamente legal en la implementación de Linux de pthreads, mira la sección de notas en pthreads_exit . Afirma

Para permitir que otros subprocesos continúen la ejecución, el hilo principal debe terminar llamando a pthread_exit () en lugar de salir (3).

Además, un vistazo al código fuente aquí (tornea el final) muestra que se traduce aproximadamente a _endthread o _endthreadex. La documentación aquí para aquellos no hace mención de no llamarlo en el hilo inicial.


Este comportamiento completamente legal e intencionado. Todo el proceso solo finaliza cuando todos los hilos terminan o exit se llama explícita o implícitamente.

Un retorno normal desde main es equivalente a una llamada para exit . Si finalizas main con pthread_exit estás diciendo explícitamente que quieres que los otros hilos continúen.


Al probar en Linux (versión 7.2.1511 (Core) de CentOS Linux) descubrí que, de hecho, el programa principal espera a que continúen los subprocesos "secundarios". Además, no pude pasar un código de retorno desde main, aunque se puede especificar como argumento para pthread_exit (), como dijo Raul arriba, siempre regresa con el código de salida 0:

retval=3; pthread_exit(&retval);

También observamos un mensaje de error al usar el compilador de Clang (versión 3.4.2) y las opciones de desinfección:

==5811==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7f4c090321d0 in thread T0 #0 0x7f4c08be3e29 in __interceptor_free (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x65e29) #1 0x7f4c08333358 in free_key_mem (/lib64/libdl.so.2+0x1358) #2 0x7f4c08745bc1 in __nptl_deallocate_tsd (/lib64/libpthread.so.0+0x7bc1) #3 0x7f4c07771b38 in __libc_start_main (/lib64/libc.so.6+0x21b38) #4 0x7f4c08bfa08c in _start (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x7c08c) AddressSanitizer can not describe address in more detail (wild memory access suspected). SUMMARY: AddressSanitizer: bad-free ??:0 __interceptor_free ==5811==ABORTING