2010-08-24 4 views
12

Wenn ich pthread_exit von main aufrufen, wird das Programm nie beendet. Ich erwartete das Programm zu beenden, da ich den einzigen Thread des Programms verließ, aber es funktioniert nicht. Es scheint aufgehängt zu sein.Ist es OK, pthread_exit von main zu rufen?

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

int main(int argc, char *argv[]) 
{ 
    printf("-one-\n"); 

    pthread_exit(NULL); 

    printf("-two-\n"); 
} 

Process Explorer zeigt, dass die (nur) Gewinde in Wait:DelayExecution Zustand befindet.

Nach pthread_exit Dokumentation:

das Verfahren mit einem Ausgang Status von 0 nach dem letzten Fadenausgang soll habe beendet. Das Verhalten soll sein, als ob die Implementierung exit() mit einem Nullargument bei Thread Beendigungszeit aufgerufen würde.

Ich verwende Dev-C++ v4.9.9.2 und pthreads-win32 v2.8.0.0 (Verknüpfung gegen libpthreadGC2.a).

Die Bibliothek scheint in Ordnung zu sein (z. B. funktioniert der Aufruf pthread_self oder pthread_create von main funktioniert gut).

Gibt es einen Grund für das, was ich nicht anrufen soll pthread_exit von main?

+1

Warum geben Sie nicht 0 zurück? 'Anstelle von' pthread_exit (NULL); '? –

+2

Ich weiß, ich _could_ 'return' oder' exit'. Ich möchte nur wissen, ob es legal ist, den Haupt-Thread durch Aufruf von 'pthread_exit' zu beenden. – user429788

+0

Die Rückkehr von main() unterscheidet sich sehr von der Ausführung von pthread_exit(). Letzterer lässt den Rest der aktiven Threads enden und beendet ihn dann mit dem Rückgabewert 0. Ersterer beendet alles sofort. –

Antwort

12

Nun, es ist definitiv legal in der Linux-Implementierung von Pthreads, siehe den Abschnitt Hinweise in pthreads_exit. Darin heißt es

andere Threads zu ermöglichen, die Ausführung fortzusetzen, sollte der Hauptthread durch pthread_exit() beenden, anstatt Ausgang (3).

Ferner ist ein Blick auf den Quellcode here (torwads das Ende) zeigt, dass es in etwa _endthread oder _endthreadex übersetzt. Die Dokumentation here für diese erwähnt nicht, es nicht im ersten Thread aufzurufen.

+0

Dann denke ich, dass es auch in der win32-Implementierung (http://sourceware.org/pthreads-win32/bugs.html) legal sein sollte. Ich habe nach einem bekannten Fehler gesucht, der dieses Verhalten erklärt, aber ich konnte es nicht finden. Meiner Meinung nach ist dies entweder ein fehlerhaftes Verhalten oder es gibt einen tatsächlichen Grund, warum ich 'pthread_exit' nicht auf' pthreads_win32' aufrufen soll. Kann jemand irgendeine dieser Hypothesen bestätigen? – user429788

+0

@matasierra: Ich habe einige Details zur Antwort hinzugefügt. Was macht eigentlich main? – torak

+0

Das erste 'printf' wird tatsächlich ausgedruckt, aber das zweite ist nicht (wie erwartet). Das Problem ist, dass das Programm nicht beendet wird. Es wird einfach irgendwie _frozen_. – user429788

12

Dieses völlig legale und beabsichtigte Verhalten. Der gesamte Prozess endet nur, wenn entweder alle Threads enden oder explizit oder implizit aufgerufen wird.

Eine normale Rückgabe von main entspricht einem Aufruf an . Wenn Sie main mit pthread_exit beenden, sagen Sie ausdrücklich, dass die anderen Threads fortgesetzt werden sollen.

0

Beim Testen unter Linux (CentOS Linux Release 7.2.1511 (Core)) habe ich festgestellt, dass das Hauptprogramm tatsächlich darauf wartet, dass "untergeordnete" Threads fortgesetzt werden. Auch ich war nicht in der Lage einen Return-Code von der Haupt heraus zu führen, obwohl es als Argument für pthread_exit angegeben werden kann(), wie Raul sagte darüber immer mit Exit-Code 0 zurück:

retval=3; 
pthread_exit(&retval); 

Wir haben auch eine beobachtetes Fehlermeldung beim Verwenden des Clang-Compilers (Version 3.4.2) und Desinfektionsoptionen:

==5811==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7f4c090321d0 in thread T0 
#0 0x7f4c08be3e29 in __interceptor_free (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x65e29) 
#1 0x7f4c08333358 in free_key_mem (/lib64/libdl.so.2+0x1358) 
#2 0x7f4c08745bc1 in __nptl_deallocate_tsd (/lib64/libpthread.so.0+0x7bc1) 
#3 0x7f4c07771b38 in __libc_start_main (/lib64/libc.so.6+0x21b38) 
#4 0x7f4c08bfa08c in _start (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x7c08c) 

AddressSanitizer can not describe address in more detail (wild memory access suspected). 
SUMMARY: AddressSanitizer: bad-free ??:0 __interceptor_free 
==5811==ABORTING