3使用2个管道进行同步

时间:2014-02-19 13:34:21

标签: c unix synchronization pipe

我正在尝试使用fork()创建2个子进程并同步它们,以便它们无限地一个接一个地显示一条消息。

e.g.   Process 1 has process (pid)
       ...
       Process 2 has process (pid)
       ...
       Process 3 has process (pid)
       ...
       Process 1 has process (pid)
       ...
       ...

我知道使用3个管道可以更容易地做到这一点,但我想知道是否可以用2进行。出于某种原因,第一个进程永远不会有机会运行。请记住,我只能用管道来解决这个问题。

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

int main()
{
    pid_t p, p1, mypid;
    int i;
    int a = 1;
    int b = 1;  
    int fd[2];      
    int fd1[2]; 
    pipe(fd);   
    p = fork();
    if (p < 0) {perror("Fork"); exit(1); }
    else if (p == 0)
    {
        mypid = getpid();        
        while(1)
        {           
            close(fd[1]);       
            if (read(fd[0], &a, sizeof(int)) == 0)                  
            {           
                for(i = 0; i < 5; i++) {printf("Process 2 has process %d\n", mypid); }      
                close(fd[0]);       
                a = 1;              
                write(fd[1], &a, sizeof(int)); } }
        }
    else
    {   
        p = fork();
        if (p < 0) {perror("Fork"); exit(1); }  
        pipe(fd1);          
        if (p > 0)
        {
            mypid = getpid();               
            while(1)
            {               
                close(fd1[1]);          
                if (read(fd1[0], &b, sizeof(int)) == 1)
                {
                    for(i = 0; i < 5; i++) {printf("Process 1 has process %d\n", mypid); }                  
                    close(fd[0]);
                    a = 0;                  
                    write(fd[1], &a, sizeof(int)); }                            
                close(fd[1]);               
                if ((read(fd1[0], &b, sizeof(int)) == 0) && (read(fd[0], &a, sizeof(int)) == 1))                
                {
                    close(fd1[0]);
                    b = 0;
                    write(fd1[1], &b, sizeof(int)); }
            } 
        }           
        else
        {               
            while(1)
            {                   
                close(fd1[1]);
                if (read(fd1[0], &b, sizeof(int)) == 0)
                {               
                    mypid = getpid();       
                    for(i = 0; i < 5; i++) {printf("Process 3 has process %d\n", mypid); }
                    close(fd1[0]);          
                    b = 1;                  
                    write(fd1[1], &b, sizeof(int)); }
            }           
        }
    }
    return(1); }

- 这是我的unix课程的一个项目,所以如果你只是指出我的错误而不是为我解决它,我会非常感激。 - 我想我误解了管道/读取的概念。如果我错过了某些内容并且可能链接来源以获取更具体的细节,请告诉我。 - 该程序可能包含一些小错误(Missing {}等)。

1 个答案:

答案 0 :(得分:2)

使用管道,您将获得两个通过管道相互连接的文件描述符。生成子进程时,文件描述符将复制到子进程。出于IPC的目的,这两个过程需要就哪个过程使用管道的哪一端达成一致。如果父亲得到结束0并且孩子得到结束1,则无关紧要,反之亦然。重要的是他们同意。把它想象成连接两个房间的物理管道。如果你在一个房间,你可以将东西放入管道或取出东西,但你只能在一端做到这一点。

在您的程序中,父级和子级都试图关闭管道的同一端,然后尝试使用管道的相同另一端。你的烟斗是一个水桶。 :)要纠正这个问题,请在您的子项中关闭您在父项中读/写的管道的末尾。在父进程中,关闭在子节点中读/写的管道的末尾。我怀疑你会有更大的成功。