2010-11-19 13 views
5

Il comportamento di questo codice è ben definito?È valido chiamare pthread_join sul thread principale?

#include <stdio.h> 
#include <pthread.h> 

pthread_t mt; 

void *start(void *x) 
{ 
    void *y; 
    pthread_join(mt, &y); 
    printf("joined main thread\n"); 
    return 0; 
} 

int main() 
{ 
    pthread_t t; 
    mt = pthread_self(); 
    pthread_create(&t, 0, start, 0); 
    pthread_exit(0); 
} 

risposta

7

Sì, questo è possibile. In effetti, questa possibilità è uno dei motivi principali per cui esiste pthread_detach(). Dalla documentazione POSIX per pthread_detach() (vedi man pthread_detach):

It has been suggested that a "detach" function is not necessary; the 
    detachstate thread creation attribute is sufficient, since a thread 
    need never be dynamically detached. However, need arises in at least 
    two cases: 

    1. In a cancellation handler for a pthread_join() it is nearly essen- 
     tial to have a pthread_detach() function in order to detach the 
     thread on which pthread_join() was waiting. Without it, it would 
     be necessary to have the handler do another pthread_join() to 
     attempt to detach the thread, which would both delay the cancella- 
     tion processing for an unbounded period and introduce a new call 
     to pthread_join(), which might itself need a cancellation handler. 
     A dynamic detach is nearly essential in this case. 


    2. In order to detach the "initial thread" (as may be desirable in 
     processes that set up server threads). 

Così che cosa si sta proponendo va bene secondo le norme.

Edit: solo per confermare che un ulteriore, i POSIX description of exec() stati:

Il filo iniziale nuova immagine del processo è fissato a accostabili, come se creato con l'attributo detachstate impostato PTHREAD_CREATE_JOINABLE.

+0

Prenderesti in considerazione l'aggiunta di un link alla tua fonte per l'ultima modifica? Credo che tu abbia capito da qui: http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html, ma volevo prima confermare. Ottima risposta, però! – currysensei

+1

@currysensei: aggiunto! – psmears

0

Non riesco a immaginare il motivo per cui si dovrebbe fare questo in un mondo reale applicazione (qualcuno si prega di commentare un esempio, se si può pensare di uno), ma io non credo che sia ancora possibile. Tutte le ricerche su pthreads che ho guardato hanno sempre chiamato il join dal thread principale, non un thread secondario.

Il join richiede inoltre che il thread a cui si sta tentando di partecipare venga creato con il flag PTHREAD_CREATE_JOINABLE. Non sono stato in grado di trovare alcuna documentazione che indichi se il thread principale è stato creato come tale.

Codeguru ha una domanda simile su di esso here che può o non può aiutare a chiarire.

Se ciò che si desidera eseguire è il thread figlio che continua dopo che il thread principale è terminato, è necessario creare il thread figlio disconnesso oppure utilizzare fork/vfork in base alla piattaforma su cui si trova.

+0

'PTHREAD_CREATE_JOINABLE' è l'impostazione predefinita in base alle POSIX; non è necessario utilizzare un 'pthread_attr_t' per ottenerlo. –

+0

A proposito, sono d'accordo sul fatto che probabilmente non è una buona pratica. Ho posto la domanda da un punto di vista sul fatto che un'implementazione debba supportare questo dubbio utilizzo, non sul fatto che uno scrittore di applicazioni debba usarlo. :-) –

0

Il tuo approccio sembra formalmente valida a me, in particolare, dal momento che si sta facendo la pthread_exit alla fine del main.

D'altra parte non ho trovato alcuna indicazione in POSIX se la filettatura iniziale di main debba essere unificata o meno. La logica nella risposta di psmears chiede solo che main debba essere staccabile da dove è stato creato univoco.

Anche qualcos'altro dannoso potrebbe chiamare pthread_detach da una subroutine chiamata da main o così. Quindi dovresti controllare definitivamente il valore di ritorno di pthread_join per verificare un caso del genere.

anche nel codice di esempio si dispone di una gara tra la creazione di start e la cessazione di main:

  • main potrebbe essere risolto prima start arriva pthread_join

Mutexing l'accesso al mt variabile dovrebbe catturare quello.

+0

Se 'pthread_detach' è già stato chiamato su un thread, il risultato della chiamata' pthread_join' su quel thread non è definito; non è necessario restituire alcun errore e infatti potrebbe bloccarsi se il thread è già terminato e le sue risorse sono state deallocate. –

+0

Supponendo che il thread principale è abbinabile, non c'è nessun problema se 'main' chiama' 'pthread_exit' prima start' chiama' pthread_join'. La semantica di un thread collegabile è come quella di un 'pid' per un processo figlio. Proprio come il 'pid' è riservato (processo zombi) finché non lo si attende e si raccoglie lo stato di uscita,' pthread_t' è valido fino a quando non si stacca o si unisce al thread, anche se è già uscito. –

+0

Non sono d'accordo con la tua prima osservazione. Un thread non collegabile è rilevabile e non porta a un risultato indefinito. 'La funzione pthread_join() è sicuro se: * * EINVAL L'implementazione ha rilevato che il valore specificato dal filo non si riferisce ad un joinable thread.' –

Problemi correlati