2015-07-11 38 views
0

我試圖運行下面的代碼。在這個question的幫助下,我能夠理解應該創建多少個進程和線程,但是,爲了讓這個更進一步,我嘗試讓線程執行一個函數。執行線程 - 輸出原因

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

void *runner(void *param) { 
    int i = atoi(param);  
    printf("My thread id is %ld\n",pthread_self()); 
    printf("\nValue of parameter = %d", i); 
    pthread_exit(0); 
} 

int main() 
{ 
    int i = 5; 
    pid_t pid; 
    pthread_t tid; 
    pthread_attr_t attr; 

    pid = fork(); wait(NULL); 

    if (pid == 0) { /* Child Process */ 

     fork(); wait(NULL); 
     pthread_attr_init(&attr); 
     i++; 
     pthread_create(&tid, &attr, runner, &i); 
     pthread_join(tid, NULL); 
    } 
    fork(); wait(NULL); 
    printf("\n\n"); 
    return 0; 
} 

這種情況的輸出是: 我的線程id是139919964464896

Value參數= 0

Value參數= 0

我的線程id是139919964464896

參數值= 0

Value參數= 0

這裏,我無法弄清楚:

  1. 爲什麼行我的線程ID爲139919964464896得到,而線值參數= 0獲取打印打印兩次四次。
  2. 爲什麼當傳遞的參數初始化爲5並增加到6時,該值會打印爲0?

請問,有人可以幫助我嗎?提前致謝!

回答

2

爲什麼行我的線程ID是139919964464896獲取打印兩次 而參數= 0的行被打印四次。

當你fork(),每個進程也從父節點(所有其他的東西)獲得緩衝區的副本。通常stdout(標準輸出)是線路緩衝的。這意味着當您打印換行符(\n)或明確清空緩衝區時,緩衝區將被刷新,即調用fflush(stdout); 當您第一次調用fork()時,緩衝區中沒有任何內容(即,目前爲止尚未打印任何內容)。所以它沒有區別。但是當第二次調用fork()時,整個未刷新的緩衝區被複制到子進程。當它退出進程時,兩個進程都會刷新其緩衝區。因此Value of parameter = 0被打印兩次。

但是行My thread id is ....而不是打印兩次,因爲\n強制緩衝區被刷新。

因此,無論在末尾添加一個新行:

printf("\nValue of parameter = %d\n", i); 
           ^forces flushing the output buffer 

或調用fork()第二次之前調用fflush(stdout);

很明顯,在第一個fork之後,你有兩個進程,它們都會創建一個線程。所以你會看到兩個線程的輸出。

+0

我剛開始閱讀操作系統,這是很多有用的信息。非常感謝解釋! :) – Neha

+0

不客氣! –

2

你的錯誤是你怎麼會在這裏解釋線程參數:

int i = atoi(param); 

特性參數的值是「&我」,從「主()」函數,所以參數是一個真正的int*對象已被轉換爲void*指針。然而,用「atoi」,你把它當作一個字符串來對待。

替換符合:

int* typed_param = (int*) param; 
int i = *typed_param; 

然後事情應該是有意義的。

+0

感謝您的糾正。請你也可以幫助我的第一點,爲什麼id的線程打印兩次和參數值4次? – Neha