我正在玩一些 fork/vfork 函数,有些事情让我感到困惑。在史蒂文斯的书中写道:
请注意,在图 8.3 中,我们调用 _exit 而不是 exit。
正如我们在第 7.3 节中所描述的,_exit 不执行任何标准 I/O 缓冲区的刷新。如果我们改为调用 exit,结果是不确定的。根据标准 I/O 库的实现,我们可能会看到输出没有差异,或者我们可能会发现父级 printf 的输出已经消失。如果子调用 exit,实现会刷新标准 I/O 流。如果这是库采取的唯一操作,那么我们将看到与子调用 _exit 时生成的输出没有区别。但是,如果实现还关闭了标准 I/O 流,则表示标准输出的 FILE 对象的内存将被清除。因为child是借用parent的地址空间,所以当parent恢复并调用printf时,不会出现任何输出,并且 printf 将返回 -1。请注意,父级的 STDOUT_FILENO 仍然有效,因为子级获得了父级文件描述符数组的副本(参见图 8.2)。大多数现代的退出实现都不会费心去关闭流。因为进程即将退出,内核会关闭进程中所有打开的文件描述符。在库中关闭它们只会增加开销而没有任何好处。
所以我尝试测试是否会出现 printf 错误,在我的 vfork 手册中有:
所有打开的 stdio(3) 流都被刷新和关闭。由 tmpfile(3) 创建的文件被删除。
但是当我编译并执行这个程序时:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
int s;
pid_t ret;
if (vfork() == 0)
{
//abort();
exit(6);
}
else
{
ret=wait(&s);
printf("termination status to %d\n",s);
if (WIFEXITED(s))
printf("normalnie, status to %d\n",WEXITSTATUS(s));
}
return 0;
}
一切正常,我没有收到任何 printf 错误。这是为什么?