2012-06-06 25 views
17

Tôi đang bắt đầu tìm hiểu một số C và trong khi nghiên cứu ngã ba, hãy đợi các chức năng tôi nhận được với một đầu ra không mong muốn. Ít nhất là cho tôi.Cách sử dụng Fork() để chỉ tạo 2 quy trình con?

Có cách nào để tạo chỉ 2 quy trình con từ cha mẹ không?

Ở đây mã của tôi:

#include <sys/types.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main() 
{ 
    /* Create the pipe */ 
    int fd [2]; 
    pipe(fd); 

    pid_t pid; 
    pid_t pidb; 


    pid = fork(); 
    pidb = fork(); 

    if (pid < 0) 
    { 
     printf ("Fork Failed\n"); 
     return -1; 
    } 
    else if (pid == 0) 
    { 
     //printf("I'm the child\n"); 
    } 
    else 
    { 
     //printf("I'm the parent\n"); 
    } 

    printf("I'm pid %d\n",getpid()); 

    return 0; 
} 

Và đây là kết quả của tôi:

I'm pid 6763 
I'm pid 6765 
I'm pid 6764 
I'm pid 6766 

Xin vui lòng, bỏ qua phần đường ống, tôi đã không nhận rằng đến nay được nêu ra. Tôi chỉ cố gắng để tạo ra chỉ có 2 quy trình con vì vậy tôi mong đợi 3 "Tôi pid ..." kết quả đầu ra chỉ có 1 cho cha mẹ mà tôi sẽ thực hiện chờ đợi và 2 quá trình con sẽ giao tiếp thông qua một đường ống.

Hãy cho tôi biết nếu bạn thấy lỗi của tôi ở đâu.

+1

'ngã ba (2) 'là cả hai rất đơn giản và một trong những cuộc gọi bị hiểu lầm nhất trong API unix. Chỉ cần nhìn vào thanh bên "Liên quan". Có lý do cụ thể nào mà bạn muốn giao tiếp giữa hai đứa con không giữa cha mẹ và đứa trẻ không? – dmckee

+0

Đối với ngã ba() gọi tại sao bạn kiểm tra pid == 0? Làm thế nào để tôi biết cái nào là cha mẹ và đứa con nào? – TwilightSparkleTheGeek

+1

@TwilightSparkleTheGeek 'man fork' quy định: TRẢ LẠI TRẢ LỜI Khi thành công, PID của quy trình con được trả lại trong cấp độ gốc và 0 được trả lại trong trẻ. Trên thất bại, -1 được trả về trong phụ huynh, không có tiến trình con nào được tạo và errno được đặt một cách thích hợp. – mimoralea

Trả lời

30
pid = fork(); #1 
pidb = fork(); #2 

Chúng ta hãy giả định quá trình cha mẹ id là 100, ngã ba đầu tiên tạo ra một quá trình 101. Bây giờ cả 100 & 101 tiếp tục thực hiện sau khi # 1, vì vậy họ thực hiện ngã ba thứ hai. pid 100 đạt # 2 tạo ra một tiến trình khác 102. pid 101 đạt # 2 tạo ra một tiến trình 103. Vì vậy, chúng ta kết thúc với 4 tiến trình.

Điều bạn nên làm là một cái gì đó như thế này.

if(fork()) # parent 
    if(fork()) #parent 
    else # child2 
else #child1 
+3

Điều đó chắc chắn hoạt động. Tuy nhiên, tôi khuyên bạn nên sử dụng câu lệnh chuyển đổi thay thế. Hàm fork có thể trả về -1 và chúng ta có thể xử lý lỗi này với case -1 bên trong câu lệnh switch. – sj755

+0

Tôi nghĩ rằng cha mẹ là sau khi tuyên bố khác. Tại sao phụ huynh trong câu lệnh if? Tôi bối rối. – TwilightSparkleTheGeek

+1

Vì ngã ba trả về 0 cho trẻ, không phải cha mẹ. Trên trang mẹ, nó trả về PID của tiến trình con bạn vừa tạo, cái này hữu ích hơn. – mimoralea

3

Khi tuyên bố ngã ba được thực hiện bởi cha mẹ, quy trình con được tạo như bạn mong muốn. Bạn có thể nói rằng quá trình con cũng thực thi lệnh fork nhưng trả về giá trị 0, cha mẹ, tuy nhiên, trả về pid. Tất cả các mã sau khi tuyên bố ngã ba được thực hiện bởi cả hai, cha mẹ đứa trẻ.

Trong trường hợp của bạn những gì đã xảy ra là câu lệnh ngã ba đầu tiên đã tạo ra một tiến trình con. Vì vậy, hiện nay có một phụ huynh, P1 và một đứa con, C1.

Bây giờ cả P1 và C1 đều gặp phải tuyên bố nhánh thứ hai. Cha mẹ tạo một đứa trẻ khác (c2) như bạn mong đợi, nhưng ngay cả đứa trẻ, c1 cũng tạo ra một tiến trình con (c3). Vì vậy, trong thực tế bạn có P1, C1, C2 và C3, đó là lý do tại sao bạn có 4 đầu ra tuyên bố in.

Cách tốt nhất để suy nghĩ về điều này là sử dụng cây, với mỗi nút đại diện cho một quy trình và nút gốc là cha mẹ trên cùng.

13

Sau khi tạo quy trình, bạn nên kiểm tra giá trị trả lại. nếu bạn không làm như vậy, số thứ hai fork() sẽ được thực hiện bởi cả quá trình cha và tiến trình con, vì vậy bạn có bốn tiến trình.

nếu bạn muốn tạo 2 tiến trình con, chỉ cần:

if (pid = fork()) { 
    if (pid = fork()) { 
     ; 
    } 
} 

Bạn có thể tạo tiến trình con n như thế này:

for (i = 0; i < n; ++i) { 
    pid = fork(); 
    if (pid) { 
     continue; 
    } else if (pid == 0) { 
     break; 
    } else { 
     printf("fork error\n"); 
     exit(1); 
    } 
} 
0

bạn có thể kiểm tra giá trị như if (pid < 0) quá trình tạo không thành công điều này cho biết việc tạo quy trình con không thành công .. ngã ba trả về id tiến trình của tiến trình con nếu getpid() được sử dụng từ lệnh cha mẹ ss ..

0

Bạn có thể tạo quy trình con trong quy trình con. Bằng cách này, bạn có thể có 2 bản sao của quy trình gốc ban đầu.

int main (void) { 
    pid_t pid, pid2; 
    int status; 

    pid = fork(); 

    if (pid == 0) { //child process 
     pid2 = fork(); 
     int status2; 

     if (pid2 == 0) { //child of child process 
      printf("friends!\n"); 
     } 
     else { 
      printf("my "); 
      fflush(stdout); 
      wait(&status2); 
     } 
    } 
    else { //parent process 
     printf("Hello "); 
     fflush(stdout); 
     wait(&status); 
    } 

    return 0; 
} 

này in như sau:

Hello my friends!