Sin locking pthread_join

Estoy codificando el cierre de un servidor multiproceso. Si todo va como debería, todos los hilos salen por sí mismos, pero hay una pequeña posibilidad de que un hilo se atasque. En este caso, sería conveniente tener una unión sin locking. entonces yo podría hacer

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

algo como esto:

 hilo foreach hacer
   nb_pthread_join ();
     si todavía está funcionando
       pthread_cancel ();

Puedo pensar en más casos en los que sería útil una unión sin locking.

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

Como otros han señalado, no hay un pthread_join sin locking 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 progtwig) tal función no es necesaria. Simplemente puede 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 de malo en llamar a pthread_cancel en todos sus hilos (terminados o no), por lo que llamar a todos sus hilos no se bloqueará y garantizará la salida del hilo (limpio o no).

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

Si está ejecutando su aplicación en Linux, le puede interesar saber que:

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

Tenga cuidado, como el sufijo lo sugiere, “np” significa “no portátil”. No son extensiones POSIX estándar, gnu, aunque útiles.

enlace a la página de manual

El mecanismo ‘pthread_join’ es una conveniencia que debe usarse si hace exactamente lo que usted desea. No hace nada que no pueda hacer usted mismo, y si no es exactamente lo que quiere, codifique exactamente lo que desea.

No hay 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.

Comienza cambiando tu forma de pensar. No es un hilo que se atasca, es lo que el hilo estaba haciendo lo que se atasca.

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

De lo contrario, puede crear un subproceso separado que ejecutará pthread_join () y alertará el subproceso padre, señalando 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.

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.

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 excedido. Su espera habrá terminado si:

  • El tiempo de espera ocurre, o
  • Si la condición está satisfecha

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: Progtwigció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 cronometrada en Pthreads.

No hay pthread_join progtwigdo, pero si está esperando que se bloquee otro hilo en condiciones, puede usar pthread_cond_timed_wait cronometrado en lugar de pthread_cond_wait

Puede insertar un byte en un conducto abierto como no bloqueante para señalar el otro hilo cuando está hecho, luego use una lectura no bloqueante para verificar el estado de la tubería.