gpt4 book ai didi

c - 标准流和 vfork

转载 作者:太空狗 更新时间:2023-10-29 11:10:31 27 4
gpt4 key购买 nike

我在玩 fork/vfork 函数,有些东西让我感到困惑。在史蒂文斯的书中写道:

Note in Figure 8.3 that we call _exit instead of exit.

As we described in Section 7.3, _exit does not perform any flushing of standard I/O buffers. If we call exit instead, the results are indeterminate. Depending on the implementation of the standard I/O library, we might see no difference in the output, or we might find that the output from the parent's printf has disappeared. If the child calls exit, the implementation flushes the standard I/O streams. If this is the only action taken by the library, then we will see no difference with the output generated if the child called _exit. If the implementation also closes the standard I/O streams, however, the memory representing the FILE object for the standard output will be cleared out. Because the child is borrowing the parent's address space, when the parent resumes and calls printf, no output will appear and printf will return -1. Note that the parent's STDOUT_FILENO is still valid, as the child gets a copy of the parent's file descriptor array (refer back to Figure 8.2). Most modern implementations of exit will not bother to close the streams. Because the process is about to exit, the kernel will close all the file descriptors open in the process. Closing them in the library simply adds overhead without any benefit.

所以我尝试测试是否会出现 printf 错误,在我的 vfork 手册中有:

All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed.

但是当我编译并执行这个程序时:

  #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 错误。这是为什么?

最佳答案

你引用的段落结尾说:

Most modern implementations of exit will not bother to close the streams. Because the process is about to exit, the kernel will close all the file descriptors open in the process. Closing them in the library simply adds overhead without any benefit.

这很可能是正在发生的事情。您的操作系统实际上并没有关闭流(但它可能会刷新它)。

重要的不是 exit 在这里做了什么,而是它的基本概念。 child 正在共享 parent 的内存和堆栈框架。这意味着 child 可以很容易地改变 parent 没有预料到的东西,这很容易导致 parent 在再次开始运行时崩溃或行为不端。 vfork 的手册页说进程唯一能做的就是调用 exit()exec。事实上, child 甚至不应该分配内存或修改任何变量。

要查看此操作的影响,请尝试将 vfork 调用放在一个函数内,让 child 返回或修改那里的一些变量,看看会发生什么。

关于c - 标准流和 vfork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10036068/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com