2016-11-12 39 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 *)' –