Domanda

Sto codificando lo shutdown di un server multithread. Se tutto va come dovrebbe tutti i thread escono da soli, ma c'è una piccola possibilità che un thread si blocchi. In questo caso sarebbe conveniente avere un join non bloccante quindi potrei farlo.

Esiste un modo per eseguire un pthread_join non bloccante?Sarebbe utile anche una sorta di unione temporizzata.

qualcosa come questo:

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

Posso pensare a più casi in cui un join senza blocco sarebbe utile.

Sembra che non esista una funzione del genere, quindi ho già codificato una soluzione alternativa, ma non è così semplice come vorrei.

È stato utile?

Soluzione

Come altri hanno sottolineato, non è disponibile un pthread_join non bloccante nelle librerie pthread standard.

Tuttavia, dato il problema indicato (cercando di garantire che tutti i thread siano terminati all'arresto del programma), tale funzione non è necessaria.Puoi semplicemente fare questo:

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");

Non c'è niente di sbagliato nel chiamare pthread_cancel su tutti i tuoi thread (terminati o meno), quindi chiamarlo per tutti i tuoi thread non bloccherà e garantirà l'uscita del thread (pulita o meno).

Ciò dovrebbe essere considerato una soluzione alternativa "semplice".

Altri suggerimenti

Se stai eseguendo la tua applicazione su Linux, potresti essere interessato a sapere che:

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

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

Attenzione, come suggerisce il suffisso, "np" significa "non portatile".Non sono standard POSIX, estensioni GNU, utili però.

collegamento alla pagina man

Il meccanismo 'pthread_join' è comodo da utilizzare se capita di fare esattamente quello che vuoi.Non fa nulla che non potresti fare da solo e, dove non è esattamente quello che vuoi, codifica esattamente quello che vuoi.

Non c'è alcun motivo reale per cui dovresti preoccuparti se un thread è terminato o meno.Ciò che ti interessa è se il lavoro svolto dal thread è stato completato.Per dirlo, chiedi al thread di fare qualcosa per indicare che sta funzionando.Il modo in cui lo fai dipende da cosa è l'ideale per il tuo problema specifico, che dipende in larga misura da cosa stanno facendo i thread.

Inizia cambiando il tuo modo di pensare.Non è un thread che si blocca, è ciò che il thread stava facendo che si blocca.

Se stai sviluppando per QNX, puoi utilizzare la funzione pthread_timedjoin().

Altrimenti, puoi creare un thread separato che eseguirà pthread_join() e avviserà il thread genitore, segnalando ad esempio un semaforo, che il thread figlio completa.Questo thread separato può restituire ciò che ottiene da pthread_join() per consentire al thread genitore di determinare non solo quando il figlio completa ma anche quale valore restituisce.

La risposta dipende davvero dal motivo per cui vuoi farlo.Se vuoi solo ripulire i thread morti, ad esempio, probabilmente è più semplice avere semplicemente un thread "pulizia thread morto" che esegue il loop e si unisce.

Non sono sicuro di cosa intendi esattamente, ma presumo che ciò di cui hai veramente bisogno sia un meccanismo di attesa e notifica.

In breve, ecco come funziona:Aspetti che una condizione venga soddisfatta con un timeout.La tua attesa finirà se:

  • Si verifica il timeout, o
  • Se la condizione è soddisfatta.

Puoi averlo in loop e aggiungere un po' più di intelligenza alla tua logica.La migliore risorsa che ho trovato per questo relativo a Pthreads è questo tutorial:Programmazione dei thread POSIX (https://computing.llnl.gov/tutorials/pthreads/).

Sono anche molto sorpreso di vedere che non esiste un'API per l'unione temporizzata in Pthreads.

Non c'è tempo pthread_join, ma se stai aspettando un altro thread bloccato in base alle condizioni, puoi utilizzare timed pthread_cond_timed_wait invece di pthread_cond_wait

È possibile inserire un byte in una pipe aperta come non bloccante per segnalare all'altro thread una volta terminato, quindi utilizzare una lettura non bloccante per verificare lo stato della pipe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top