2012-08-09 10 views
15

Ich habe ein Problem über Haupt-Thread und anderen Thread in demselben Prozess. Wenn die Hauptfunktion zurückkehrt, wird der andere Thread ebenfalls beendet? Ich habe etwas verwirrt mich. Und ich schreibe einige Test-Code, wie folgt aus: "Haupt-Thread return"Haupt-Thread-Ausgang, andere Ausgänge auch?

void* test1(void *arg) 
{ 
    unsigned int i = 0; 
    while (1){ 
     i+=1; 
    } 
    return NULL; 
} 

void* test2(void *arg) 
{ 
    long double i = 1.0; 
    while (1){ 
     i *= 1.1; 
    } 
    return NULL; 
} 

void startThread (void * (*run)(void*), void *arg) { 
    pthread_t t; 
    pthread_attr_t attr; 
    if (pthread_attr_init(&attr) != 0 
     || pthread_create(&t, &attr, run, arg) != 0 
     || pthread_attr_destroy(&attr) != 0 
     || pthread_detach(t) != 0) { 
    printf("Unable to launch a thread\n"); 
    exit(1); 
    } 
} 

int main() 
{ 
    startThread(test1, NULL); 
    startThread(test2, NULL); 

    sleep(4); 
    printf("main thread return.\n"); 

    return 0; 
} 

Wenn die raus, thread test1 und test2 auch exit, kann mir jemand sagen warum?

+0

Der Text der Frage stimmt nicht mit dem Fragetext überein. Geht es darum, was passiert, wenn der Haupt-Thread beendet wird? Oder ist es das, was passiert, wenn der Haupt-Thread von der Hauptfunktion zurückkehrt? (Natürlich kann der Thread nicht zurückkehren, wenn er beendet wird. Er kann das eine oder das andere tun.) –

Antwort

9

Wenn der Haupt-Thread zurückkehrt, wird der gesamte Prozess beendet. Dies schließt alle anderen Threads ein. Das gleiche passiert, wenn Sie 10 anrufen.

Der Zweck von pthread_detach ist, es so zu machen, dass Sie nicht mit anderen Threads verbinden müssen, um ihre Ressourcen freizugeben. Das Entfernen eines Threads bewirkt nicht, dass er nach dem Abschluss des Prozesses existiert, er wird zusammen mit allen anderen Threads zerstört.

+16

Diese Antwort ist wie geschrieben nicht wahr. Wenn der Hauptthread (oder irgendein Thread) "exit" aufruft oder wenn der anfängliche Aufruf von "main" zurückkehrt, wird der gesamte Prozess beendet. Der Haupt-Thread kann jedoch mit 'pthread_exit' enden, ohne andere Threads zu beeinflussen. –

19

Sie sollten pthread_join() für jeden der neuen Threads verwenden, um den aufrufenden Thread zu informieren, auf die Unterthreads zu warten und die Ausführung - und den Prozessende - auszusetzen, bis diese Threads beendet werden.

Aufruf pthread_detach auf den erstellten Threads wird nicht halten sie herum, nachdem ein Prozess beendet. Aus dem linux man page:

Das losgelöste Attribut bestimmt lediglich das Verhalten des Systems, wenn der Thread beendet wird; Es verhindert nicht, dass der Thread beendet wird, wenn der Prozess mit exit (3) beendet wird (oder äquivalent, wenn der Hauptthread zurückkehrt).

Sie werden manchmal pthread_exit in main statt explizite pthread_join Anrufe, wobei die Absicht verwendet, dass main auf diese Weise verlässt anderen Threads weiterlaufen lassen wird. In der Tat, die linux man page Staaten dies ausdrücklich:

Um andere Threads zu ermöglichen die Ausführung fortzusetzen, sollte der Haupt-Thread beenden, indem pthread_exit() aufgerufen wird, anstatt Ausgang (3).

Aber ich weiß nicht, ob dies erwartetes Verhalten auf allen Plattformen ist, und ich habe immer auf pthread_join verwendet.

pthread_join erfordert die pthread_t für den Ziel-Thread, so dass Ihr Code ein bisschen ändern muss, da Sie beide Threads vor dem Aufruf pthread_join erstellen müssen, um auf beide zu warten. Sie können es also nicht startThread nennen. Sie müssen eine pthread_t zurückgeben oder einen Zeiger an eine pthread_t an Ihre startThread Funktion übergeben.

+1

Aber ich benutze pthread_detach-Funktion, um dies zu vermeiden. – laifjei

+2

Lesen Sie die Dokumentation für ['pthread_detach'] (http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_detach.html) sorgfältig durch. Es tut nicht, was du zu denken scheinst. – pb2q

+0

@laifjei Vielleicht verwechseln Sie mit der bereitgestellten Funktionalität e. G. in Java/C#/Python/etc. - Daemon-Threads. Java intern hält den Prozess am Leben, während alle Nicht-Daemon-Threads am Leben bleiben (obwohl der Haupt-Thread stirbt). –