如何使用"匿名"用于C中进程同步的管道?

时间:2012-08-19 17:37:42

标签: c process synchronization pipe

我一直很难理解命令管道()在C中是如何工作的。据我所知,匿名管道用于在两个“相关”进程之间发送/接收信息。
我发现在相应的文件描述符中读取和写入的条件非常混乱,并且不理解为什么必须关闭读取fd才能写入和反之,以及如何使用它来阻止进程直到另一个人读过或写过
如何使用管道来同步进程?例如,如何使用pipe()实现以下流程层次结构?

A / B ----D\
  \ C ------\
             E


-A必须在创建B和C之前完成 -B必须在创建D之前完成 -C和C必须在E创建之前完成 -B和C可以任何顺序完成

非常感谢您的帮助

2 个答案:

答案 0 :(得分:2)

我已经模拟了您提到的流程同步,并提供了注释。希望这个概念现在很清楚。

注意这里没有通过管道读取数据,它仅用于通过使用读取功能的阻塞特性实现同步,当管道的写入端仍然打开时。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#define MAXBUF 1

int main(){

    int ret, i, fd[2];
    char buf[MAXBUF];

    //Create a Pipe
    pipe(fd);

    ret = fork();//Creating process A
    if (0 == ret)
    {
            printf("Process - A created\n");
            exit(0);
    }
    //I need to wait till Process - A completes
    //Let me close my write end else I will be blocked for ever in the loop below
    close(fd[1]);

    //Waiting over reading the pipe -> The loop will come out when Process A exits
    //Why ->since all the write ends of the pipe are closed, so read returns 0
    while ((ret = read(fd[0], buf, MAXBUF)) > 0)
    {
            //Just Wait, the read blocks till A exits and then read returns 0
    }
    //Again a pipe to synchronise B and C
    pipe(fd);

    //Lets Create Now  B and C

    ret = fork();
    if (0 == ret)
    {
            printf("Process - B created\n");
            exit(0);
    }
    ret = fork();
    if (0 == ret)
    {
            printf("Process - C created\n");
            exit(0);

    }
    //Let me close my Write End of pipe
    close(fd[1]);

    //Here Waiting for Termination of both B and C who can terminate in any order.
    while ((ret = read(fd[0], buf, MAXBUF)) > 0)
    {
            //This loop will turn false only if both B & C have exited.
            //Since both the write ends of the pipe that
            //were there in B and C will no longer be available
            //after they exit and thus the read will return 0
            //Just Wait ..Do nothing
    }
    //Now all A, B, C are finished.
    //Create D and E
    ret = fork();
    if (0 == ret)
    {
            printf("Process - D created\n");
            exit(0);
    }
    ret = fork();
    if (0 == ret)
    {
            printf("Process - E created\n");
            exit(0);

    }
//Here let the main process wait for all the 5 Child to complete
    //This is not needed, but I gave given so that the Shell
    //Prompt is shown after the code exits..
    //If this is deleted then you need to press return
    //to get back the shell prompt after the code completes execution.
    for (i = 0; i < 5; i++)
    {
            wait(NULL);
    }

}

答案 1 :(得分:1)

管道不用于进程同步,而不是直接用于进程同步。相反,这是一种沟通方式。

例如,进程创建一对管道(一个写端和一个读端),然后分叉,从而创建一个新的子进程。然后,父级可以通过管道将数据发送到子进程。