2017-03-04 58 views
1

我正在寫我的第一個叉管代碼,以瞭解它是如何工作的。3叉和6管

問題是我想創造3個與他父親交流的孩子,每個孩子將執行不同的任務。

這是我工作的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 

int main(void) 
{ 
    int nbytes; 
    int  fd1[2], fd11[2]; /*fd1-->child1*/ 
    int  fd2[2], fd21[2]; /*fd2-->child2*/ 
    int  fd3[2], fd31[2]; /*fd3-->child3*/ 
    pid_t child1, child2, child3; 
    char string[] = "Hello, world!\n"; 
    char string1[] = "Shuting Down\n"; 
    char readbuffer[80]; 

    printf("child1-->%d\n", child1); 
    if (child1==0 && child2==0 && child3==0){ 

     printf(" HOLA-> pid %d\n", getpid()); 

     if(pipe(fd1)==-1 || pipe(fd11)==-1){ //Creating Pipes for son 1 
      perror("pipe"); 
      exit(-1); 
     } 
     if(pipe(fd2)==-1 || pipe(fd21)==-1){ //Creating Pipes for son 2 
      perror("pipe"); 
      exit(-1); 
     } 
     if(pipe(fd3)==-1 || pipe(fd31)==-1){ //Creating Pipes for son 3 
      perror("pipe"); 
      exit(-1); 
     } 

     if((child1 = fork()) == -1){ 
      perror("fork"); 
      exit(-1); 
     } 

     /*Creating child 2 and 3*/ 
     if((child2 = fork()) == -1){ 
      perror("fork"); 
      exit(-1); 
     } 
     if((child3 = fork()) == -1){ 
      perror("fork"); 
      exit(-1); 
     } 

    } 
    if(child1==0){ // Child 1 

     close(fd2[0]);close(fd21[0]);close(fd3[0]);close(fd31[0]); 
     close(fd2[1]);close(fd21[1]);close(fd3[1]);close(fd31[1]); 
     close(fd1[1]); /* Son process closes up output side of pipe */ 
     close(fd11[0]); /* Son process closes up input side of pipe */ 

     /* Read in a string from the pipe */ 
     read(fd1[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm SON1 -->Received string: %s\n", readbuffer); 

     printf("LOADING...\n");   
     sleep(2); 

     write(fd11[1], "SON1-->Shuting Down\n", (strlen("SON1-->Shuting Down\n")+1)); 
     printf("I'm SON1 -->send string & shutdown\n"); 

     exit(0); 

    }else if(child2==0){ // Child 2 

     close(fd1[0]);close(fd11[0]);close(fd3[0]);close(fd31[0]); 
     close(fd1[1]);close(fd11[1]);close(fd3[1]);close(fd31[1]); 
     close(fd2[1]); /* Son process closes up output side of pipe */ 
     close(fd21[0]); /* Son process closes up input side of pipe */ 

     /* Read in a string from the pipe */ 
     read(fd2[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm SON2 -->Received string: %s\n", readbuffer); 

     printf("LOADING...\n");   
     sleep(2); 

     write(fd21[1], "SON2-->Shuting Down\n", (strlen("SON2-->Shuting Down\n")+1)); 
     printf("I'm SON2 -->send string & shutdown\n"); 

     exit(0);  

    }else if(child3==0){ // Child 3 

     close(fd2[0]);close(fd21[0]);close(fd1[0]);close(fd11[0]); 
     close(fd2[1]);close(fd21[1]);close(fd1[1]);close(fd11[1]); 
     close(fd3[1]); /* Son process closes up output side of pipe */ 
     close(fd31[0]); /* Son process closes up input side of pipe */ 

     /* Read in a string from the pipe */ 
     read(fd3[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm SON3 -->Received string: %s\n", readbuffer); 

     printf("LOADING...\n");   
     sleep(2); 

     write(fd31[1], "SON3-->Shuting Down\n", (strlen("SON3-->Shuting Down\n")+1)); 
     printf("I'm SON3 -->send string & shutdown\n"); 

     exit(0);  


    }else{ // DAD Code  

     close(fd1[0]);close(fd2[0]);close(fd3[0]); /* Father process closes up input side of pipe */ 
     close(fd11[1]);close(fd21[1]);close(fd31[1]); /* Father process closes up output side of pipe */ 

     /* Send "string" through the output side of pipe */ 
     write(fd1[1], string, (strlen(string)+1)); 
     printf("I'm the father -->send string to SON1\n"); 

     write(fd2[1], string, (strlen(string)+1)); 
     printf("I'm the father -->send string to SON2\n"); 

     write(fd3[1], string, (strlen(string)+1)); 
     printf("I'm the father -->send string to SON3\n"); 


     read(fd11[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm the father -->SON1 Received string: %s", readbuffer); 

     read(fd21[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm the father -->SON2 Received string: %s", readbuffer); 

     read(fd31[0], readbuffer, sizeof(readbuffer)); 
     printf("I'm the father -->SON3 Received string: %s", readbuffer); 

     sleep(2); 
     printf("Father shuting down\n"); 
     exit(0); 

    } 

    return(0); 
} 

我的問題是,當我執行的代碼,它apears類似的東西:

I'm the father -->send string to SON1 
I'm the father -->send string to SON2 
I'm the father -->send string to SON3 
I'm SON3 -->Received string: Hello, world! 

LOADING... 
I'm SON2 -->Received string: Hello, world! 

LOADING... 
I'm SON1 -->Received string: Hello, world! 

LOADING... 
I'm SON3 -->send string & shutdown 
I'm SON2 -->send string & shutdown 
I'm SON1 -->send string & shutdown 
I'm the father -->SON1 Received string: SON1-->Shuting Down 
I'm the father -->SON2 Received string: SON2-->Shuting Down 
I'm the father -->SON3 Received string: SON3-->Shuting Down 
Father shuting down 

V:~$ I'm SON2 -->Received string: 
LOADING... 
I'm SON1 -->Received string: 
LOADING... 
I'm SON1 -->Received string: 
LOADING... 
I'm SON1 -->Received string: 
LOADING... 

我的問題是:在哪裏¿對兒子的四次呼喚是從哪裏來的? ¿我錯過了什麼?

任何幫助,將不勝感激!

謝謝你提前和對不起我的拼寫錯誤

+0

哪種語言,C或C++?他們是兩種不同的語言。 C++語言支持線程。 C++語言具有'std :: string',C不具有。 –

+0

哪個平臺?標準的C語言不支持線程,因爲它是平臺特定的問題。 –

+0

女士們,先生們,[叉子炸彈]。(https://en.wikipedia.org/wiki/Fork_bomb) – user4581301

回答

6

好吧我現在。你的錯誤是你分叉的方式如下:

if ((child1 = fork() == -1) { 
    // handle error 
} 

if ((child2 = fork()) == -1) 
.. 
.. 
.. 

叉後,創建一個新的進程副本。它將從與父母相同的位置繼續。它還將執行下一個分支
第一個分支後,將創建一個新子。然後在第二個分支後,你將有4個進程執行第三個分支。結束了8個進程。假設fork sys調用沒有失敗。

如果你想然後創建僅3流程應該是這樣:

Child1 = fork(); 
if (Child1 == -1) { // handle error } 
if (Child1 == 0) { // child process } 
if (Child1 > 0) 
{ 
    Child2 = fork(); 
    if (Child2 == -1) ... 
    if (child2 == 0)... 
    if (child2 > 0) 
    { 
     Child3 = fork();.... 
    } 
    . 
    . 
5

就讓我們看看這段代碼:

if((child1 = fork()) == -1){ 
     perror("fork"); 
     exit(-1); 
    } 
    /*Creating child 2 and 3*/ 
    if((child2 = fork()) == -1){ 
     perror("fork"); 
     exit(-1); 
    } 
    if((child3 = fork()) == -1){ 
     perror("fork"); 
     exit(-1); 
    } 

假設沒有叉的失敗,後先叉,你將有兩個進程(父母和孩子),這兩個進程從這一點繼續。因此,兩者都會執行第二個分支,爲您提供4個進程(父級,2個子級和孫子),所有進程都進入第3個分支,之後您有8個進程...