0

我已經完成了以下代碼。使用pthread_exit()訪問返回值

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

struct foo 
{ 
    int a; 
    int b; 
}; 

void* thread_func1(void *arg) 
{ 
    struct foo *temp = (struct foo*)malloc(sizeof(struct foo)); 

    temp->a = 10; 
    temp->b = 20; 

    pthread_exit(temp); 
} 

void* thread_func2(void *arg) 
{ 
    pthread_exit((void*)100); 
} 

int main() 
{ 
    pthread_t tid1, tid2; 
    int err; 
    struct foo *f; 
    void *ret; 

    err = pthread_create(&tid1, NULL, thread_func1, NULL); 
    err = err | pthread_create(&tid2, NULL, thread_func2, NULL); 

    if(err != 0) 
    { 
     perror("pthread_create()"); 
     exit(-1); 
    } 

    err = pthread_join(tid1, (void**)&f); 
    if(err != 0) 
    { 
     perror("pthread_join1"); 
     exit(-1); 
    } 

    printf("a = %d, b = %d\n", f->a, f->b); //Line1 

    err = pthread_join(tid2, &ret); 
    if(err != 0) 
    { 
     perror("pthread_join2"); 
     exit(-1); 
    } 

    printf("ret = %d\n", *(int*)ret); //Line2 

    return 0; 

} 

我在Line2上出現分段錯誤。什麼是錯線2

如果我修改線路2至

的printf( 「RET =%d \ n」 個,(int)的RET);

沒有分段錯誤,它打印正確的值(即100)。我不明白爲什麼修改可行。我相信我有關於使用雙指針的錯誤概念。我想要糾正它。

分段錯誤的原因是什麼以及修改的原因是什麼?

+0

旁註:使用'malloc'這樣的:'結構FOO * TEMP =的malloc(的sizeof(*溫度));'當你理解了好處,你會欣賞它。 – Shahbaz

+0

與您的問題無關,但不釋放第一個線程函數返回的值。 –

+0

@JoachimPileborg:點注意!在使用f-> a和f-> b訪問值之後,'free'必須完成嗎? –

回答

2

您從線程返回一個數字。在第一個線程中,該號碼是struct foo *。因此,如果你說

pthread_join(tid1, &ret); 

然後ret將包含指針(這是雙指針)。

類似地,在第二種情況下,即使您正在查看它,就好像它是void *一樣,即將返回100。儘管如此,價值仍然是100

因此,當你寫

pthread_join(tid2, &ret); 

ret將包含100,這不是一個指針,但僅僅是整數。這就是爲什麼你也應該把它投到int

您遇到分段錯誤的原因是您將100視爲int *,然後嘗試對其進行解引用。

3

這是因爲你正在返回實際的整數,而不是一個指針,但你可以作爲指針訪問它。

+1

+1偉大的思想想象,你打敗了我14秒:) – Brady

+1

@Brady是啊也許... :)但你的答案包含一個替代解決方案。 –

1

它,因爲你想dereferencce的指針,其地址爲100

而不是看的返回值,你爲什麼不一個指針,要在thread_funcs分配傳遞什麼?也就是說,使用thread_func1的 「無效* ARG」 參數()和thread_func2()

像這樣:

void* thread_func1(void *arg) 
{ 
    struct foo **fooPtrPtr = (struct foo**) arg; 
    *fooPtrPtr = (struct foo*)malloc(sizeof(struct foo)); 

    ... 
} 

void* thread_func2(void *arg) 
{ 
    int *intPtr = arg; 
    *intPtr = 100; 
    ... 
} 

int main() 
{ 
    pthread_t tid1, tid2; 
    int err; 
    struct foo *f; 
    int ret; 

    err = pthread_create(&tid1, NULL, thread_func1, &f); 
    err = err | pthread_create(&tid2, NULL, thread_func2, &ret); 
    ... 
    printf("a = %d, b = %d\n", f->a, f->b); //Line1 
    ... 
    printf("ret = %d\n", ret); //Line2 
    ... 
} 
1

pthread_exit((void*)100);導致整數100成爲您線程的退出狀態。它只是濫用類型轉換,因此void*是它的類型。 如果你想取出這個值,你將不得不在主線程中使用同一類型轉換濫用,以及:

int ret; 
err = pthread_join(tid2, (void**) &ret); 
// here you can work with ret as with any other integer 

我也建議你使用return,而不是pthread_exit。另請注意,使用malloc動態分配的內存應通過調用free來釋放。而且這裏的malloc返回值的類型重複是冗餘的,可以省略。

這個問題也可以幫助你:Close a thread when done with it