以下是代码:
// after fork:
else if (pid > 0) // parent
{
char buff[READ_SIZE];
write(STDOUT_FILENO, "parent\n", 7);
int r = read(STDIN_FILENO, buff, READ_SIZE);
if (r == -1)
perror("parent");
}
else // child
{
char buff[READ_SIZE];
write(STDOUT_FILENO, "child\n", 6);
int r = read(STDIN_FILENO, buff, READ_SIZE);
if (r == -1)
perror("child");
sprintf(buff, "\n%d", r);
write(STDOUT_FILENO, buff, 2);
}
这是输出:
$ ./forktest
parent
child
abc <-- input goes to parent, parent exits
$ <-- both child and terminal waiting for input, presumably
此时,只要按任意键(不按Enter键),我就会:
$ ./forktest
parent
child
abc
$
1 <-- the child has read just 1 character
这意味着孩子的read()只在一次按键后没有回复就结束了。
为什么?
PS。我知道正确的做法是让父母为孩子等待()。我只是好奇这里到底发生了什么。
答案 0 :(得分:0)
stdin 始终有效,直到您关闭终端应用程序。
stdin是由您的终端创建的,而不是bash,而不是父级。只要您的终端处于活动状态,stdin就会激活
大多数shell(bash / dash / zsh)将tty设置为逐字节模式读取,当你按任意键时,read会立即返回,因为它们正在自动完成。
当shell要启动程序时,它将tty设置为行模式,程序逐行读取。
但是一旦父进程退出,shell就会将tty重置为字节模式,因为你的孩子和shell共享相同的tty,它也会影响你的孩子,所以你的孩子会读取一个字符。
答案 1 :(得分:0)
您的shell喜欢以原始模式工作,但会将终端设置为熟化模式以生成程序。你可以在任何地方阅读有关原始模式和熟食模式的信息。但简单地说,在原始模式中,输入是逐个字符的,而在熟食模式下,它是逐行的。
那会发生什么?省略多余的事件: