2015-09-29 20 views
5

Xin chào! Tôi đã làm việc trên một chương trình dành cho trẻ em và sau đó sẽ chia thêm trẻ em từ mỗi đứa trẻ nhưng đó không phải là những gì tôi cần trợ giúp với. Khi tôi chạy chương trình của tôi (ở đây nó là một chức năng nhưng hoạt động giống nhau) Tôi có nghĩa là có một cha mẹ (PPID) đẻ trứng 3 trẻ em (PIDS = 1,2,3) nhưng những gì tôi nhận được là một trong hai PID và PPID cùng 3 lần (mã hiện tại của tôi) hoặc trước khi tôi nhận được 3 phụ huynh với mỗi phụ huynh có một đứa con và PPIDS khác nhau cũng như PIDS, nhưng PPID cũng giống như các PID con trước đó. Trong những nỗ lực mới nhất của tôi, nó không bao giờ hiển thị thông báo cha (cha) phía trên đứa trẻ (con trai). Hình ảnh trông giống như thế nàysử dụng fork() để làm 3 trẻ em trong số 1 phụ huynh trong C (không phải C++)

[dad] hi am I PID 1234 and I come from ####(dont care what this number is) 
[son] hi i am PID 1111 and I come from PPID 1234 
[son] hi i am PID 1112 and I come from PPID 1234 
[son] hi i am PID 1113 and I come from PPID 1234 

đây là mã của tôi. Tôi chỉ tìm kiếm gợi ý nếu có thể, trừ khi nó chỉ là một sai lầm ngớ ngẩn tôi đã thực hiện như "oh chỉ cần di chuyển ngã ba() cho quá trình con" hoặc một cái gì đó như thế.

Tôi cũng có một child_count chỉ để tôi có thể dễ dàng đếm số trẻ em.

int forking(null) 
{ 
     void about(char *); 
     int i=0; 
     int j=0; 
     int child_count =0; 
     about("dad"); 

    for(i = 0; i < 3; i++){ 
     pid_t child = 0; 
     child = fork(); 


      if (child < 0) { //unable to fork error 
        perror ("Unable to fork"); 
        exit(-1);} 

      else if (child == 0){ //child process 
        about ("son"); 
        printf("I am child #%d \n",child_count); 
        child_count++; 
        exit(0);} 

      else { //parent process (do nothing) 

       } 
      } 

       for(j = 0; j < 3; j++){ 
          wait(NULL);//wait for parent to acknowledge child process 
          } 
return 0; 
} 
+3

Hai điều cần nhớ: Đầu tiên là một khi bạn đã chia hai, quá trình con có được một bản sao của ký ức về cha mẹ, và khi đứa trẻ sẽ thay đổi ví dụ biến các biến đó chỉ được thay đổi ở trẻ, cha mẹ (hoặc bất kỳ "anh chị em" nào) sẽ không thấy những thay đổi biến đó. Điều thứ hai là bạn gọi 'wait' trong trường hợp' else' sẽ chặn cả cha lẫn mẹ * và * con. –

+3

Ồ, và bạn có một trường hợp xấu * hành vi không xác định * trong mã của bạn. Bạn định nghĩa biến 'child', nhưng sau đó bạn sử dụng nó * trước * bạn khởi tạo nó. Các biến cục bộ chưa được khởi tạo có giá trị * không xác định *, sử dụng chúng mà không cần khởi tạo dẫn đến UB. Bạn có thể muốn suy nghĩ về nơi bạn gọi là "ngã ba". –

+0

oh ý bạn là pid_t child = 0? Những gì bạn có nghĩa là chờ đợi() khối cả cha mẹ và con? Và về bản sao bộ nhớ, bạn có thể cho tôi một mã ví dụ không? Nó làm cho nó dễ dàng hơn để xem điểm đó. – Jite

Trả lời

4

Phụ huynh cần phải
- in nhắn
- gọi ngã ba ba lần
- chờ cho ba đứa con để thoát

Mỗi đứa trẻ cần phải
- in nhắn
- thoát

Vì vậy, mã đơn giản như

int main(void) 
{ 
    printf("[dad] pid %d\n", getpid()); 

    for (int i = 0; i < 3; i++) 
     if (fork() == 0) 
     { 
      printf("[son] pid %d from pid %d\n", getpid(), getppid()); 
      exit(0); 
     } 

    for (int i = 0; i < 3; i++) 
     wait(NULL); 
} 

mà tạo ra sản lượng này

[dad] pid 1777 
[son] pid 1778 from pid 1777 
[son] pid 1779 from pid 1777 
[son] pid 1780 from pid 1777 
+0

Tôi cập nhật nó. Cái này thế nào? – Jite

2

Một trong những điều bạn phải nhớ là, khi bạn fork, cả phụ huynh và trẻ em sẽ tiếp tục chạy mã tại điểm đó.

Vì vậy, nếu bạn không phát hiện chính xác trẻ em/cha mẹ, trẻ sẽ có nhiều khả năng bắt đầu riêng trẻ em của chúng.

Một cách tốt để bạn có thể bắt đầu lên ba đứa con và không có cháu là sử dụng một bộ đếm kết hợp với quá trình ID trở về từ các fork cuộc gọi, dọc theo dòng trong các cách sau:

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

#define COUNT 3 

int main(void) { 
    # Desired and actual count. 

    int count = COUNT, children = 0; 

    // Force parent initially. 

    pid_t retpid = 1; 

    // Only fork if limit not reached AND is parent (children 
    // will exit loop with retpid == 0). 

    while (count-- > 0 && retpid > 0) 
     // Adjust actual count if successful. 

     if ((retpid = fork()) > 0) 
      children++; 

    // Detect parent, all forks returned non-zero. 

    if (retpid != 0) { 
     printf("Parent %d spawned %d/%d children\n", 
      getpid(), children, COUNT); 

     // Wait for children to finish. 

     while (children-- > 0) 
      wait(NULL); 
    } else { 
     // Otherwise you were one of the children. 

     printf("Child %d, sired by %d\n", getpid(), getppid()); 
    } 

    return 0; 
} 

đầu ra này những gì bạn dường như sau tuy nhiên, do sự thay đổi bất thường của lịch trình, không nhất thiết theo thứ tự:

Parent 26210 successfully spawned 3/3 children 
Child 26212, sired by 26210 
Child 26213, sired by 26210 
Child 26211, sired by 26210 

việc kiểm tra của PID trở sẽ đảm bảo chỉ phụ huynh không bất kỳ forking, và số lượng sẽ giới hạn nó đến một số lượng cụ thể.


Một điều bạn cũng cần lưu ý là bộ đệm đầu ra. Khi bạn ngã ba, bạn có thể kết thúc với hai quy trình với dữ liệu đầu ra đệm.

Trường hợp thiết bị đầu ra có thể được phát hiện là thiết bị đầu cuối, thường sẽ xuất hiện trên dòng mới, vì vậy các cuộc gọi printf của bạn có thể sẽ không bị trùng lặp đầu ra cho một lần chạy bình thường.

Bạn chỉ cần lưu ý rằng bạn có thể nhận được các kết quả thú vị nếu bạn chuyển hướng kết quả của mình sang tệp chẳng hạn.

Các vấn đề liên quan