2011-12-14 70 views
1


我正在與我的教授的講義做一個審查。當我到達併發部分時,我得到了這個問題:
在幻燈片中,教授給出了兩個使用pthread的例子(一個是很好的例子,另一個是壞的)。但我不明白爲什麼他們之間有區別。
這裏是很好的例子:C程序併發與pthread

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
    int *nump = malloc(sizeof(int)); 
    srand(pthread_self()); 
    *nump = rand(); 
    return nump; 
} 
int main() { 
    pthread_t tid; 
    void *ptr = NULL; 
    pthread_create(&tid, NULL, get_rand_num, NULL); 
    pthread_join(tid, &ptr); 
    printf("Random number: %d\n", * (int *) ptr); 
    return 0; 
} 

而壞的例子是

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
    int num; 
    srand(pthread_self()); 
    num = rand(); 
    return &num; 
} 
int main() { 
    pthread_t tid; 
    void *ptr = NULL; 
    pthread_create(&tid, NULL, get_rand_num, NULL); 
    pthread_join(tid, &ptr); 
    printf("Random number: %d\n", * (int *) ptr); 
    return 0; 
} 

任何人都可以理解這兩個例子,請向我解釋爲什麼壞的是從第一個不同,爲什麼它不好?


謝謝
艾倫

回答

5

壞例子返回一個指向一個局部變量。這總是一個壞主意,因爲局部變量在函數返回時死亡。這並不是多線程程序特有的問題,但由於線程每個線程獲得一個堆棧,所以在pthread_join之後解除分配。雖然你經常在單線程編程中很幸運,並且可以在函數返回後立即使用指針,但是包含舊線程堆棧的整個段可能已經返回到操作系統的壞例子,並且訪問會產生段錯誤。

第一個例子也不是很好,因爲它會產生內存泄漏。

+0

謝謝,我想我明白了!順便說一句,在第一個例子中,你的意思是應該通過添加一行來釋放分配的內存來改進它。如「免費(nump)」?你認爲我應該把這一行放在程序中?我應該把它放在`pthread_join()`之前嗎? – 2011-12-14 18:53:20

+0

從技術上講,由於程序壽命短,OS在程序終止時自動回收內存,因此沒有內存泄漏,只是不好的做法。 – Ioan 2011-12-14 18:54:53

1

在不好的情況下,您的返回& num,其中num是堆棧上的局部變量,僅在函數作用域中有效。一旦你回來,它不再有效。

0

不好的情況下會返回一個指向堆棧的指針 - 就像很久以前飛出窗口的小鳥!

但是,如果它的工作 - 你將有一個非常非常隨機的數字 - 更好一點,隨機數字gerenrator與線程的ID!