2016-11-12 41 views
1

分段錯誤你能解釋爲什麼在Linux中(而不是在蘋果機)我得到段錯誤,當我做:更改順序將返回在Linux上

pthread_join(thread2, (void**)&status); 
pthread_join(thread1, (void**)&status); 

不過是確定的,當我做:

pthread_join(thread1, (void**)&status); 
pthread_join(thread2, (void**)&status); 

我想在Mac上,一切都很好,但在Linux的代碼運行正常只有當我的加入線程1的,之後的加入的線程2 ...

這是我的代碼:

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

void *print_msg(char *ptr); 

main(){ 
    pthread_t thread1, thread2; 
    char *message1 = "Ping"; 
    char *message2 = "Pong"; 
    int status; 
    pthread_create(&thread1, NULL, print_msg, message1); 
    printf("tid thread1= %d\n", (int)thread1); 
    pthread_create(&thread2, NULL, print_msg, message2); 
    printf("tid thread2= %d\n", (int)thread2); 
    pthread_join(thread2, (void**)&status); 
    pthread_join(thread1, (void**)&status); 
    printf("Thread 1 end with: %d\n", (int)status); 
    printf("Thread 2 end with: %d\n", (int)status); 
    exit(0); 
} 

void *print_msg(char *ptr){ 
    char *msg; 
    void *val=0; 
    msg = (char *) ptr; 
    printf("%s \n", msg); 
    pthread_exit(val); 
} 
+3

您可能想要先修復所有編譯器警告,有幾個。你可以用'-Wall'和'-Wextra'編譯你的代碼,這會告訴你很多潛在的錯誤。你也可以讀作[並行線程DOC(http://man7.org/linux/man-pages/man3/pthread_create.3.html),其中包含例如如何使用'在pthread_join()' – SSC

回答

-1

我想我已經想通了。

的問題是,Linux沒有足夠的時間來創建所有它需要什麼,因爲我們要求的加入立刻來管理線程。 如果我們之間解決這個問題只需要插入連一個愚蠢的指令:

... 
pthread_create(&thread1, NULL, print_msg, message1); 
printf("tid thread1= %d\n", (int)thread1); 
pthread_create(&thread2, NULL, print_msg, message2); 
int a=0; 
pthread_join(thread2, (void**)&status); 
pthread_join(thread1, (void**)&status); 
... 
+2

完全不正確。看到我的答案。 – selbie

+0

此外,以上似乎工作的原因可能是因爲你插入了一個新的堆棧變量'a'。由於它遵循聲明順序中的「status」,它可能就是吸收緩衝區溢出的東西。如果在從pthread_join返回之後'a'的值已經改變,我不會感到驚訝。 – selbie

0

你的(void**)&status投的問題。

status是在它的未初始化值的整數。這也不是一個指針。 sizeof(status)可能4.當sizeof(void*)可能8.因此被調用時,在pthread_join,這將垃圾4個字節的堆棧的過去status堆棧位置。這很可能是主函數的返回地址。但在這一點上,我們處於未定義的行爲領域。

變化status聲明是一個void*。正如你應該使用任何指針值,將它初始化爲NULL。那就是:

void* status = NULL; 

隨後,簡化您在pthread_join語句,所以你不需要投。

pthread_join(thread2, &status); 
pthread_join(thread1, &status); 
+0

這很好,注意到這與'pthread_create'的啓動例程的類型一致:void *(* start_routine)(void *)' –