Pregunta

Estoy codificando el cierre de un servidor multiproceso. Si todo va como debería, todos los subprocesos salen solos, pero existe una pequeña posibilidad de que un subproceso se atasque. En este caso sería conveniente tener una unión sin bloqueo. así podría hacerlo.

¿Existe alguna forma de realizar un pthread_join sin bloqueo?Algún tipo de unión cronometrada también sería buena.

algo como esto:

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

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

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

¿Fue útil?

Solución

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

Sin embargo, dado el problema indicado (tratar de garantizar que todos los subprocesos hayan cerrado al cerrar el programa), dicha función no es necesaria.Simplemente puedes 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 subprocesos (terminados o no), por lo que llamarlo para todos sus subprocesos no se bloqueará y garantizará la salida del subproceso (limpio o no).

Esto debería calificarse como una solución alternativa "simple".

Otros consejos

Si está ejecutando su 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);

Ojo, como sugiere el sufijo, "np" significa "no portátil".No son extensiones gnu estándar POSIX, aunque son útiles.

enlace a la página de manual

El mecanismo 'pthread_join' es útil si hace exactamente lo que usted desea.No hace nada que no puedas hacer tú mismo y, cuando no sea exactamente lo que deseas, codifica exactamente lo que deseas.

No hay ninguna razón real por la que debas preocuparte si un hilo ha terminado o no.Lo que le importa es si se completó el trabajo que estaba haciendo el hilo.Para saberlo, haga que el hilo haga algo para indicar que está funcionando.La forma de hacerlo depende de lo que sea ideal para su problema específico, lo que depende en gran medida de lo que estén haciendo los subprocesos.

Empiece por cambiar su forma de pensar.No es un hilo lo que se atasca, lo que se atasca es lo que estaba haciendo el hilo.

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

De lo contrario, puede crear un subproceso separado que realizará pthread_join() y alertará al subproceso principal, indicando a 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 principal determine no solo cuándo completa el hijo sino también qué valor devuelve.

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

No estoy seguro de qué quieres decir exactamente, pero supongo que lo que realmente necesitas es un mecanismo de espera y notificación.

En resumen, así es como funciona:Espera a que se cumpla una condición con un tiempo de espera.Tu espera terminará si:

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

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

También estoy muy sorprendido de ver que no existe una API para la unión programada en Pthreads.

no hay cronometrado pthread_join, pero si estás esperando que otro hilo se bloquee en condiciones, puedes usar cronometrado pthread_cond_timed_wait en lugar de pthread_cond_wait

Puede insertar un byte en una tubería abierta como sin bloqueo para indicarle al otro hilo cuando haya terminado, luego usar una lectura sin bloqueo para verificar el estado de la tubería.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top