2012-01-14 8 views
5
void child(int pid){ 
    printf("Child PID:%d\n",pid); 
    exit(0);  
} 
void parent(int pid){ 
    printf("Parent PID:%d\n",pid); 
    exit(0); 
} 

void init(){ 
    printf("Init\n");//runs before the fork 
} 


int main(){ 

    init();//only runs for parent i.e. runs once 
    printf("pre fork()");// but this runs for both i.e. runs twice 
    //why??? 

    int pid = fork(); 

    if(pid == 0){ 
     child(pid); //run child process 
    }else{ 
     parent(pid);//run parent process 
    } 
    return 0; 
} 

đầu ra:Hệ thống Unix fork() gọi điều gì sẽ chạy khi nào?

Init 
pre fork()Parrent PID:4788 
pre fork()Child PID:0 

Tôi có một quá trình trong một hệ điều hành Unix (Ubuntu trong trường hợp của tôi). Tôi không thể cho cuộc sống của tôi hiểu cách thức hoạt động này. Tôi biết chức năng fork() tách các chương trình của tôi thành hai quy trình nhưng từ đâu? Liệu nó có tạo ra một quy trình mới và chạy lại toàn bộ chức năng chính không, và nếu vậy tại sao init() chỉ chạy một lần và printf() hai lần?

Tại sao printf("pre fork()"); chạy hai lần và chức năng init() chỉ một lần?

Trả lời

22

Chỉ có một quy trình cho đến ngã ba. Đó là, con đường đó được thực hiện chỉ một lần. Sau khi ngã ba có 2 quy trình để mã theo sau cuộc gọi hệ thống đó được thực hiện bởi cả hai quy trình. Những gì bạn bỏ qua là cả hai chấm dứt và cả hai sẽ gọi exit.

Trong mã của bạn, bạn không được flushing stdio. Vì vậy, cả hai quá trình làm điều đó (thoát ra khỏi bộ đệm stdio) - đó là lý do tại sao bạn đang thấy đầu ra đó.

Hãy thử điều này:

printf("pre fork()\n"); 
        ^^ should flush stdout 

Hoặc có thể

printf("pre fork()\n"); 
fflush(stdout); 
+0

thanks a lot. thực sự hữu ích: D – boogie666

+0

Wow, điều này rất tinh tế! +1 từ tôi! –

+2

Đơn giản chỉ cần đặt một dòng mới trong không nhất thiết phải tuôn ra bộ đệm. Chạy mã với stdout được chuyển hướng đến một tệp thông thường và bạn sẽ thấy chính xác cùng một hành vi. stdout là * không * dòng đệm theo mặc định trừ khi nó là một tty. –