更好地了解管道

时间:2015-12-31 08:01:23

标签: c unix pipe fork

在学习管道的过程中,我错误地编写了以下代码

int main()
{
    pid_t pid;
    int status;
    int p1[2];

    pid = fork();
    pipe(p1);

    if(pid==0)
    {
        dup(p1[0], 0);
        close(p1[1]);
        execv(abs_addr_of_some_bin , argv);
    }
    else
    {
        dup(p1[1] , 1);
        close(p1[0]);
        write(p1[1] , some_rand_text , size_of_text);
        wait(&status);
    }
}

正在执行的二进制文件具有read(0 , buf , size)语句,该语句从STDIN读取。

好吧,上面的代码显然不正确,因为我在fork()之前有pipe()。因此,当我尝试在另一个二进制文件中输出buf时,它会在每次执行此文件时打印一些不同的随机值。 这背后的原因可能是什么?

另外,如果我更正了我的代码(即在pipe()之前调用fork()),那么有些与管道工作有关的事情会让我感到困惑:

  1. 由于p1数组对于两个进程(父进程和子进程)都有不同的内存地址,操作系统如何知道p1 [0]的另一端(在子进程中)是p1 [ 1](在父母中)?

  2. 在此过程中会发生什么样的记忆操作?

  3. 提前致谢!

1 个答案:

答案 0 :(得分:1)

不要在叉子之后但之前创建管道!如果在之后创建它,则创建两个不相关的管道...因为您需要为两个进程共享相同的管道,所以在分叉之前创建它。

您有随机值,因为您的管道未连接且某些内容未真正测试read过程中的exec

关于地址。没有p1在父母和孩子中具有完全相同的地址!但是这些地址位于不同的地址空间中。地址过程操作总是相对于给定的地址空间。

fork复制父进程的地址空间,并为子进程构建了一个严格的副本。