2008-09-16 16 views
20

Estoy codificando el cierre de un servidor multiproceso. Si todo va como debería, todos los hilos salen por sí solos, pero hay una pequeña posibilidad de que un hilo se atasque. En este caso sería conveniente tener una unión sin bloqueo para poder hacerlo.Sin bloqueo pthread_join

¿Hay alguna manera de hacer un pthread_join sin bloqueo? Algún tipo de unión cronometrada sería bueno también.

algo como esto:

 
foreach thread do 
    nb_pthread_join(); 
    if still running 
     pthread_cancel(); 

se me ocurren más casos en los que un no-bloking unirse sería útil.

Como parece que no existe tal función, entonces ya he codificado una solución, pero no es tan simple como me gustaría.

+1

unión de rosca sin bloqueo? Pensé que unirme era todo sobre el bloqueo: s –

Respuesta

1

Como otros han señalado, no existe un pthread_join sin bloqueo disponible en las bibliotecas pthread estándar.

Sin embargo, dado su problema establecido (tratando de garantizar que todos sus hilos hayan salido al apagar el programa) tal función no es necesaria.Usted puede simplemente hacer esto:

int killed_threads = 0; 
for(i = 0; i < num_threads; i++) { 
    int return = pthread_cancel(threads[i]); 
    if(return != ESRCH) 
     killed_threads++; 
} 
if(killed_threads) 
    printf("%d threads did not shutdown properly\n", killed_threads) 
else 
    printf("All threads exited successfully"); 

No hay nada malo con llamar pthread_cancel en todas sus hilos (terminados o no) así que llamar que para todas sus hilos no bloqueará y garantizará salida de rosca (limpio o no)

Eso debería calificar como una solución 'simple'.

+22

Esta respuesta es incorrecta. Habiendo llamado con éxito 'pthread_cancel' en cada hilo no garantiza que todos los hilos hayan salido. Es posible que no hayan llegado a ningún punto de cancelación, o incluso si lo han hecho, el hilo principal podría programarse primero y regresar de 'main', lo que mataría el proceso, antes de que los otros hilos puedan terminar de limpiar ... –

0

Puede insertar un byte en un conducto abierto como no bloqueante para indicar al otro hilo cuando está hecho, luego use una lectura sin bloqueo para verificar el estado del conducto.

1

La respuesta realmente depende de por qué quieres hacer esto. Si solo quieres limpiar subprocesos muertos, por ejemplo, probablemente sea más fácil tener un hilo "limpiador de subprocesos muertos" que gire y se una.

1

No estoy seguro de qué quiere decir exactamente, pero asumo que lo que realmente necesita es un mecanismo de espera y notificación.

En resumen, así es como funciona: Esperas a que se cumpla una condición con un tiempo de espera. Su espera será más si:

  • Se produce el tiempo de espera, o
  • Si la condición se cumple.

Puede tener esto en un bucle y agregar algo más de inteligencia a su lógica. El mejor recurso que he encontrado para esto relacionado con Pthreads es este tutorial: Programación de hilos POSIX (https://computing.llnl.gov/tutorials/pthreads/).

También estoy muy sorprendido de ver que no hay API para la unión temporizada en Pthreads.

1

No hay cronometrada pthread_join, pero si usted está esperando otro hilo bloqueado en condiciones, se puede utilizar en lugar de cronometrado pthread_cond_timed_waitpthread_cond_wait

2

Si está desarrollando para QNX, puede utilizar la función pthread_timedjoin().

De lo contrario, puede crear un subproceso separado que ejecutará pthread_join() y alertará al subproceso padre, al señalar un semáforo, por ejemplo, que el subproceso secundario se completa. Este hilo separado puede devolver lo que se obtiene de pthread_join() para permitir que el hilo padre determine no solo cuando el hijo termina, sino también qué valor devuelve.

21

Si está ejecutando la aplicación en Linux, es posible que le interese saber que:

int pthread_tryjoin_np(pthread_t thread, void **retval); 

int pthread_timedjoin_np(pthread_t thread, void **retval, 
           const struct timespec *abstime); 

tener cuidado, ya que el sufijo indica, "NP" significa "no portátil". No son extensiones POSIX estándar, gnu, aunque útiles.

link to man page

9

El mecanismo 'pthread_join' es una conveniencia para ser utilizado si pasa a hacer exactamente lo que quiere. No hace nada que no pueda hacer usted mismo, y si no es exactamente lo que quiere, codifique exactamente lo que desea.

No existe una razón real por la que realmente deba importar si un hilo ha finalizado o no. Lo que te importa es si se completó el trabajo que estaba haciendo el hilo. Para decirlo, haz que el hilo haga algo para indicar que está funcionando. Cómo lo hace depende de lo que es ideal para su problema específico, que depende en gran medida de lo que están haciendo los hilos.

Comience cambiando su manera de pensar. No es un hilo que se atasca, es lo que el hilo estaba haciendo lo que se atasca.

+0

¿Quieres agregar el código de muestra? Tengo casi el mismo problema, un proceso llama a dos hilos y debería salir solo una vez que los hilos salen: ninguna de las respuestas aquí explica cómo hacer algo similar a la función fork() de fork. (Agregué esta pregunta a favoritos, me lo notificará una vez que responda automáticamente) –

+2

Tiene un booleano, protegido por un mutex, que almacena el estado de lo que desea saber. Si lo desea, use una variable de condición para indicarle el cambio del booleano. –

+0

Gracias. El código de muestra sería útil, pero podría intentar buscar en otro lugar también. –