【发布时间】:2015-12-31 08:01:23
【问题描述】:
在学习管道的时候,不小心写了如下代码
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 读取。
好吧,上面的代码显然是不正确的,因为我在pipe() 之前有fork()。因此,当我尝试在另一个二进制文件中输出buf 时,它会打印一些随机值,每次执行此文件时都会有所不同。
这可能是什么原因?
另外,如果我更正我的代码(即在fork() 之前调用pipe()),与管道工作相关的某些事情会让我感到困惑:
由于
p1数组对于两个进程(父进程和子进程)都有不同的内存地址,操作系统如何知道 p1[0] 的另一端(在子进程中)是 p1[1] (在父级中)?在这个过程中会发生什么样的内存操作?
提前致谢!
【问题讨论】:
-
how does the OS know that the other end of p1[0] (in the child) is p1[1]:一个进程有一个结构,其中有打开的文件和管道的列表。当您执行fork时,孩子会收到相同的管道。 fork 是一个系统函数,在 linux 内核中可用(它的名字是 __sys_fork)。 -
@Pierre - 是什么让你认为 fork() 只存在于 linux 中,或者使用“unix”标签的人对 linux 特别感兴趣
-
@Arlie Stephens:我从没说过。至少在所有 POSIX OS 中都有。并且对于信息,在 Windows 中没有/没有对
fork的内核系统调用。一些编译器添加了 fork 的实现。