c - 3个 fork 和6个 pipe

标签 c fork

我正在编写我的第一个叉管代码以了解它是如何工作的。

关键是我想创建 3 个 child ,他们将与他的父亲交流,每个 child 将执行不同的任务。

这是我正在处理的代码:

#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[] = "Shutting 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-->Shutting Down\n", (strlen("SON1-->Shutting 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-->Shutting Down\n", (strlen("SON2-->Shutting 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-->Shutting Down\n", (strlen("SON3-->Shutting 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 shutting down\n");
        exit(0);
    }

    return(0);
}

我的问题是,当我执行代码时,它看起来像这样:

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-->Shutting Down
I'm the father -->SON2 Received string: SON2-->Shutting Down
I'm the father -->SON3 Received string: SON3-->Shutting Down
Father shutting 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...

我的问题是:对儿子的四声呼唤从何而来?我错过了什么?

最佳答案

好的,我现在知道了。你的错误是你正在通过以下方式 fork :

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

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

fork之后,创建了一个新的进程副本。它将从与 parent 相同的位置继续。它还将执行下一个fork
在第一次 fork 之后,创建了一个新的 child 。然后在第二个 fork 之后,您将有 4 个进程将执行第三个 fork。最终有 8 个进程。假设 fork 系统调用没有失败。

如果你只想创建 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();....
    }
  .
  .

关于c - 3个 fork 和6个 pipe ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42590422/

相关文章:

c - 在父进程和子进程之间共享用于 stdio 缓冲的缓冲区是否合法?

c - 了解管道、fork 和 exec - C 编程

c - 无法在我的程序中找到段错误点

c - 反向(字符 * s,int 暗淡);在不使用 strlen 的情况下递归反转字符串

c - 一次唤醒所有线程,无需互斥体

linux - 父/子进程关闭文件描述符

c - 如果我想为同一个父对象创建多个子对象,fork() 是如何工作的?

c - 在内核模块中,如何知道给定路径是文件还是目录?

c++ - 将有符号整数位复制到无符号整数的有效方法

c++ - wait(NULL) 似乎导致 child 停止执行