- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在玩 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/
是否可以使用克隆来模拟 vfrok 的行为?到目前为止我有 pid=clone(fn,cStack,SIGCHLD|CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_
这是“APUE”第 8 章中的练习(练习 8.2,第 2 版)。所有描述是: Recall the typical arrangement of memory in Figure 7.6. Becau
我的问题是执行时父堆栈会发生什么? main() { f(); g(); } f() { vfork(); } g() { int blast[100],i; f
我在 C 中使用 vfork() 工作。我的程序运行良好,但我收到有关隐式声明的警告。 我的代码: if(vfork()==0){ ... } 我的警告是: 函数“vfork”的隐式声明 [-Wimp
因为 vfork 在与父进程相同的地址空间中创建子进程,当在子进程上调用 execv() 时,父进程如何恢复,因为 exec 加载文件并在相同的地址运行它 parent 和 child 的空间? 最佳
#include #include #include #include int createproc(); pid_t pid; int main() { createproc();
为什么这个程序永远不会返回并继续创建子进程? int main() { pid_t pid; int foo1 = 1, foo2 = 2; printf("before fo
考虑以下代码: int main() { int pid; pid=vfork(); if(pid==0) printf("child\n"); else prin
我有一个具有未定义行为的程序(vfork() 使用不当): #include #include #include int main ( int argc, char *argv[] ) {
我读到使用 vfork() 系统调用创建的新进程作为父进程地址空间中的线程执行,直到子线程不调用 exit() 或 exec() 系统调用,父进程被阻塞。所以我用 vfork() 系统调用写了一个程序
下面的代码永远不会结束。这是为什么? #include #include #include #define SIZE 5 int nums[SIZE] = {0, 1, 2, 3, 4}; in
子进程在vfork()后如何修改或读取父进程中的数据?子进程是否可以直接访问父进程中声明的变量? 我有一个创建一些数据结构的过程。然后我需要 fork 一个子进程需要读/写这些数据结构。子进程将是一个
我在玩 fork/vfork 函数,有些东西让我感到困惑。在史蒂文斯的书中写道: Note in Figure 8.3 that we call _exit instead of exit. As w
本文研究的主要是Linux进程函数fork(),vfork(),execX()的相关内容,具体介绍如下。 函数fork() fork函数:创建一个新进程 1、fork()成功后,将为子进程
使用 vfork() 创建的进程是否具有与创建者进程(即父进程)相同的权限级别? 示例:如果我以 root 身份运行进程,vfork() 子进程是否拥有相同的执行权限? 最佳答案 fork() 的开放
#include #include #include #include #include #include int main() { pid_t child_pid = vfork();
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
我想用 vfork() 编写一个程序,父级创建 n 个子级,我想用参数插入儿子的数量。然后我想计算儿子的数量,例如: ./sum 4 The sum of the child: 10 The sum
我必须创建一个程序: 索要电话号码 创建子进程(使用 vfork) 计算平方根(在子进程中) 显示父进程的平方根 这是我的代码 #include #include #include #inclu
这是我的代码...我不知道为什么会出现错误段...有人可以向我解释原因吗? #include #include // Required by for routine #include #incl
我是一名优秀的程序员,十分优秀!