2017-08-16 1 views
-2

Ich habe den folgenden Code geschrieben, um die pthread-Bibliothek POSIX mit:glibc pthread_join Absturz beim Aufruf pthread_join() zweimal

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

void *thread_function(void *arg) { 
    char *code = "1"; 
} 

int main() { 
int res; 
pthread_t a_thread; 
void *thread_result; 

res = pthread_create(&a_thread, NULL, thread_function, NULL); 
if (res != 0) { 
    perror("Thread creation failed"); 
    exit(EXIT_FAILURE); 
} 

sleep(5); 
printf("\nWaiting for thread to finish...\n"); 
res = pthread_join(a_thread, &thread_result); 
printf("res[%d]\n",res); 
if (res != 0) { 
    perror("Thread join failed"); 
    exit(EXIT_FAILURE); 
} 
res = pthread_join(a_thread, &thread_result); 
printf("res[%d]\n",res); 
exit(EXIT_SUCCESS); 
} 

Auf der Ausführung des Codes ich die folgende Ausgabe bekommen:

Waiting for thread to finish... 
res[0] 
Segmentation fault (core dumped) 

In der code, ich möchte testen Was passiert, wenn Sie die pthread_jion() - Funktion zweimal aufrufen, nachdem der Thread beendet ist. Der erste Aufruf der Funktion ist korrekt, und der zweite Absturz. Der Backtrace:

Core was generated by `./a.out'. 
Program terminated with signal SIGSEGV, Segmentation fault. 
#0 pthread_join (threadid=140150565050112, thread_return=0x7fffa0a2c508) at 
pthread_join.c:47 
47 if (INVALID_NOT_TERMINATED_TD_P (pd)) 
(gdb) bt 
Python Exception exceptions.ImportError No module named gdb.frames: 
#0 pthread_join (threadid=140150565050112, thread_return=0x7fffa0a2c508) at 
pthread_join.c:47 
#1 0x00000000004008d5 in main() 

Und ich die pthread_join.c Datei überprüfen:

39 int 
40 pthread_join (threadid, thread_return) 
41  pthread_t threadid; 
42  void **thread_return; 
43 { 
44 struct pthread *pd = (struct pthread *) threadid; 
45 
46 /* Make sure the descriptor is valid. */ 
47 if (INVALID_NOT_TERMINATED_TD_P (pd)) 
48  /* Not a valid thread handle. */ 
49  return ESRCH; 

In der Zeile 47, die Makrodefinition überprüft, ob die pd ein gültiger Thread-Handle ist. Wenn nicht, geben Sie ESRCH (3) zurück. Jedoch

wenn ich den gleichen Code in einer anderen Linux-Umgebung ausführen, bekam ich die folgende Ausgabe:

Waiting for thread to finish... 
res[0] 
res[3] 

Hat es etwas mit der Umwelt zu tun? Die beiden Linux-Systeme haben die gleiche LDD-Version:

ldd (GNU libc) 2.17 

gleichen GLIBC:

GLIBCXX_3.4 
GLIBCXX_3.4.1 
GLIBCXX_3.4.2 
GLIBCXX_3.4.3 
GLIBCXX_3.4.4 
GLIBCXX_3.4.5 
GLIBCXX_3.4.6 
GLIBCXX_3.4.7 
GLIBCXX_3.4.8 
GLIBCXX_3.4.9 
GLIBCXX_3.4.10 
GLIBCXX_3.4.11 
GLIBCXX_3.4.12 
GLIBCXX_3.4.13 
GLIBCXX_3.4.14 
GLIBCXX_3.4.15 
GLIBCXX_3.4.16 
GLIBCXX_3.4.17 
GLIBCXX_3.4.18 
GLIBCXX_3.4.19 
GLIBCXX_3.4.20 
GLIBC_2.3 
GLIBC_2.2.5 
GLIBC_2.14 
GLIBC_2.17 
GLIBC_2.3.2 
GLIBCXX_FORCE_NEW 
GLIBCXX_DEBUG_MESSAGE_LENGT 

und die gleiche Linux-Kernel-Version:

Red Hat Enterprise Linux Server release 6.6 (Santiago) 

Antwort

2

pthread_join Anrufe pthread_detach nach der Thread beendet hat. pthread_detach gibt alle Threadressourcen frei, wenn der Thread beendet wird.

Aus der Dokumentation von pthread_detach

Versuch, ein bereits freistehenden Fäden Ergebnisse in nicht spezifiziert Verhalten zu lösen.

Sie haben also ein nicht spezifiziertes Verhalten, so dass Sie nicht garantieren können, was danach passiert.

Zumindest wird der Speicher, auf den threadid zeigt, freigegeben, was zum Zugriff auf freigegebenen Speicher führt.

Kurz gesagt, rufen Sie nicht pthread_join zweimal auf der gleichen Threadid. Warum willst du?

Edit: Noch einfacher: der Mann Seite für pthread_join sagt:

mit einem Gewinde Joining, die zuvor Ergebnisse in undefinierten Verhalten verbunden ist.

Verwandte Themen