2012-02-21 101 views
3
int main(){ 

    char ch; 

    fork(); 

    cin >> c; 
} 

调用fork()后,我应该有2个确切的进程运行相同的代码。为什么在运行这个简单的例子之后,我要么只输入一次字符,要么输入两次?每次运行此程序时,系统是否都需要2次输入?fork()发生了什么?

>./a.out 
a 
>./a.out 
a 
b 
> 
+2

这不是C代码,您使用的是C++运算符,因此我们这些不会说C++的人不能帮助您。 – tbert 2012-02-21 14:10:39

+0

第二个过程很有可能会得到在'a'后面输入的\ n字符。尝试将'ch'的类型改为'std :: string',看看会发生什么。 – dasblinkenlight 2012-02-21 14:12:06

+0

我刚刚做了,它的行为方式也是一样。 – 2012-02-21 14:14:09

回答

6

您有两个进程在同一时间从终端读取。有人猜测哪个进程得到了输入。

  • 如果父进程首先获取输入,它将退出并将控制权返回给shell。 (请注意,这实际上会导致相同情况的重复,并且shell和子进程争夺输入。)
  • 如果子进程首先获取输入,则它会退出,但控制不会返回到shell直到父进程退出。

如果您有两个进程从同一个终端读取,您不应该期待一致的行为。

+0

请注意,在第一种情况下,第二个进程迟早会得到一行输入。在shell提示符后,也许;在这种情况下,它似乎会从shell中窃取一条线。 – 2012-02-21 14:42:39

+0

@James我怀疑它:父进程将关闭,即使它没有收到它要求的输入,孩子也会关闭。 – 2012-02-21 14:49:10

+1

@ Cookie503父进程无法关闭子进程中的打开fd。问题是这个fd点在哪里。如果它指向一个物理终端(一个实际设备),该设备保持打开状态。如果它指向逻辑终端(窗口,远程登录等),则逻辑设备保持打开状态,但它指向的位置或对未来IO的反应如何可能改变,例如,会话组发生了变化。 – 2012-02-21 15:05:48

2

调用fork()时,操作系统通常复制正在执行的程序的整个内存空间(排序)。这两个程序然后运行。唯一的区别是,在“新”进程中,fork()返回0,在“旧”进程中返回新进程的进程ID。

您只需要输入一个输入的原因是其中一个程序正在后台运行。命令行shell一次只能执行一个进程的I/O。

1

fork()创建一个子进程。

但是哪一个进程(在父辈和新出生的孩子之间)得到CPU片是未确定的。当两个进程都被阻止进行键盘输入时,子进程或父进程可以获得输入。 如果父节点获取该令牌,它会将输入读入其地址空间中定义的变量并退出。而孩子从来没有机会从输入中读取。这个孤儿过程将被'根'过程采用(pid = 1)。见ps输出。

而在另一种情况下,如果孩子获取令牌并读取数据并退出,则父级仍处于活动状态,因此会再次阻止输入。

+0

即使父母退出,孩子仍然应该是同一个终端组的一部分,不是吗? (我不确定,自从我在这个层次上工作已经有一段时间了)。在这种情况下,迟早会得到一条线 - 它不再与已退出的父亲竞争,而是与壳。 – 2012-02-21 14:44:44

0

在fork()后加入wait()并尝试。