2011-12-12 14 views
8

GDB me dice que pthread_kill está causando un error de segmentación en mi programa. Básicamente, estoy usando pthread_kill para comprobar si un hilo está vivo o no, dado su ID.Error de segmentación causado por pthread_kill

He estado buscando en la web y he descubierto que es posible que pthread_kill esté causando un error de segmentación cuando TID no es válido. Sí, he estado probando mi programa usando TID "inválidos" (inventados por mí) del tipo int. ¿Podría ser esa la verdadera causa?

+0

¿Qué valores "inválidos" estás usando? –

+0

@DanFego Por ejemplo, 1001 –

+0

Dado que pthread_t es un tipo opaco, usar un número entero (como 1001) teóricamente podría causar problemas y un bloqueo posterior. ¿Recibes advertencias compilando con -Wall? –

Respuesta

14

pthread_t no es una identificación de subproceso o un índice numérico. Es un tipo opaco. La creación de valores puede provocar un bloqueo.

En Linux NTPL, pthread_t se utiliza como un puntero:

int 
__pthread_kill (threadid, signo) 
    pthread_t threadid; 
    int signo; 
{ 
    struct pthread *pd = (struct pthread *) threadid; 

Debe ser bastante clara donde las cosas van mal ya :) Tenga en cuenta que este pointerness es también un detalle de implementación - la mayor aplicación Linuxthreads utilizado índices numéricos en una tabla, y allí usted podría inventar TID y no esperar que las cosas se cuelguen.

Necesita seguir el hilo de la vida y la muerte usted mismo. Un pthread_t es válido hasta que llame al pthread_join con éxito. Si desea probar si un válidopthread_t está activo, llame al pthread_tryjoin_np en él; si devuelve EBUSY, el hilo está activo. Si la función tiene éxito, el pthread_t ya no es válido; no debe volver a utilizarlo en este punto, por lo que debe anotar en alguna parte que ese hilo está muerto ahora, ¡y ya no es necesario que lo verifique más!

Podrías, por supuesto, implementar tu propio sistema de seguimiento: crear una tabla en algún lugar de vida, un sistema para distribuir TID y pasarlos a los subprocesos creados recientemente. Haga que cada hilo se marque como muerto antes de salir (tal vez usando pthread_cleanup_push para manejar la cancelación de hilo y pthread_exit), y separe el hilo para que no tenga que unirlo (usando pthread_detach). Ahora tiene control explícito de su informe de muerte por hilos.

+1

La página de manual de [pthread_kill] (https://www.kernel.org/doc/man-pages /online/pages/man3/pthread_kill.3.html) dice que puedes usar 'pthread_kill (t, 0)' para 'verificar la existencia de t', lo que implica poder realizar la llamada con valores inválidos de pthread_t. ¿página incorrecta? – Brandon

+1

@Brandon vea http://sourceware.org/bugzilla/show_bug.cgi?id=4509 y http://udrepper.livejournal.com/16844.html.dreppers argumento sems intelectualmente perezoso, pero parece que no hay intención de apoyar pthread_kill en TIDs inválidos en glibc, por lo que el enfoque de usar pthread_kill para probar la existencia del hilo no es funcional –

+0

@JoshuaClayton gracias por los enlaces. – Brandon

1

Para superar esta limitación en mi código, me puse el TID a cero cuando el código no se está ejecutando

memset(&thread, '\0', sizeof(pthread_t)); 

... y compruebe que no nula antes de llamar pthread_kill

//this code will run if thread is not valid 
if (!thread || ESRCH == pthread_kill(thread, 0)) { 
    //do stuff and create the thread 
} 
Cuestiones relacionadas