叔叔和nephwew之间的管道

时间:2018-05-23 20:35:52

标签: c pipe fork

所以我有以下代码

const int CMAX = 1048578;

int main(int argc, char *argv[]){
    int fd[2];
    pid_t v1, v2, v3, a;
    if( pipe( fd ) == -1 ){
        puts("Failed to create pipe !\n" );
        return 1;
    }
    v1 = fork();
    if(v1 == 0){
        close(fd[0]);
        write(fd[1], "hello", CMAX);
        printf("v1      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
    }
    if(v1 > 0){
        v2 = fork();
        if(v2 == 0){    
            printf("v2      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
        }
        if(v2 > 0){
            v3 = fork();
            if(v3 == 0){
                printf("v3      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
                a = fork();
                if(a == 0){
                    printf("a       Parent's PID = %ld;  Child's PID = %ld\n", getppid(), getpid());
                    close(fd[1]);
                    char buf[CMAX];
                    int bytes = read(fd[0], buf, CMAX);
                    printf("Message: %s\nSize: %d", buf, bytes);
                    }
                }
            }
    }
    return 0;
}

输出以下文字:

v2      Parent's PID = 23859; Process' PID = 23861
v1      Parent's PID = 23859; Process' PID = 23860
v3      Parent's PID = 23859; Process' PID = 23862
a       Parent's PID = 23862;  Child's PID = 23863
Message: 
Size: 0

我想从v1进程向a进程发送消息(或任何类型的数据)。我想我必须在其他过程中关闭管道,但不知道如何。我尝试在每个过程中关闭它们但没有成功(也许我把它们弄错了)。

2 个答案:

答案 0 :(得分:0)

正如aschepler所说,我写了太多字节到我的缓冲区。所以正确的版本是write(fd[1], "hello", 6);(或任何合理的值)。

答案 1 :(得分:0)

  

我想从v1进程发送消息(或任何类型的数据)   一个过程。我想我必须在其他过程中关闭管道但是   不确定如何。

应关闭在各种进程中未使用的管道端,尤其是管道的写入端,但如果不这样做,则不会阻止其他进程之间通过管道进行通信。相反,存在死锁和/或无法终止的风险,但您现有的特定代码不会受到影响。

然而,我不确定你的意思是“不确定如何”。您的代码演示了您知道如何使用close()并且您知道如何使用fork()的返回值来区分父进程和子进程。唯一的另一件事是计时:确保每个进程关闭任何文件描述符,只有在分配了需要获得自己的开放副本的所有子项后才会关闭它。

  

我尝试在每个过程中关闭它们但没有成功   (也许我错了他们)。

您似乎对read()write()存在一些误解。特别是,

  • 这些是低级函数,他们对字符串一无所知。那么,当您write()时,您必须准确指定要写入的字节数。您不能指望写入停止在字符串终止符处。同样,当您read()时,您必须指定您有兴趣接收的最大字节数,虽然您可以通过该通道传输字符串终止符,但read()不会在事件中自动提供一个字符串终结符你没有。

  • 然而,您传递的字节数是 maximums 。实际上可以传输的字节数少于实际数量。此外,读取和写入大小不一定相关。也就是说,除非您将它们构建到您自己传输的数据中,否则没有消息边界。

考虑到这些因素,如果我更正你的程序来编写和读取6个字节,那么这足以让它为我产生预期的输出。然而,这仍然会在传输大小方面留下一些潜在的问题(短写和短读不受保护)。