在学习管道的过程中,我错误地编写了以下代码
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()
),那么有些与管道工作有关的事情会让我感到困惑:
由于p1
数组对于两个进程(父进程和子进程)都有不同的内存地址,操作系统如何知道p1 [0]的另一端(在子进程中)是p1 [ 1](在父母中)?
在此过程中会发生什么样的记忆操作?
提前致谢!
答案 0 :(得分:1)
不要在叉子之后但之前创建管道!如果在之后创建它,则创建两个不相关的管道...因为您需要为两个进程共享相同的管道,所以在分叉之前创建它。
您有随机值,因为您的管道未连接且某些内容未真正测试read
过程中的exec
。
关于地址。没有p1
在父母和孩子中具有完全相同的地址!但是这些地址位于不同的地址空间中。地址过程操作总是相对于给定的地址空间。
fork复制父进程的地址空间,并为子进程构建了一个严格的副本。