fork与exit、_exit的配合使用

简介:
#include "light.h"

int main(int argc, char *argv[])
{
    printf("Hello world\n");
    write(STDOUT_FILENO, "Ciao\n", 5);
    if (fork() == -1)
        errExit("fork");
    /* Both child and parent continue execution here */
    exit(EXIT_SUCCESS);
}

When we run this program with standard output directed to the terminal, we see the expected result:
$ ./fork_stdio_buf
Hello world
Ciao
However, when we redirect standard output to a file, we see the following:
$ ./fork_stdio_buf > a
$ cat a
Ciao
Hello world
Hello world


Why?
recall that the stdio buffers are maintained in a process's user-space memory.
Therefore, these buffers are duplicated in the child by fork(). When standard out-put is 
directed to a terminal, it is line-buffered by default, with the result that the newline-terminated 
string written by printf() appears immediately. However, when standard output is directed to a 
file, it is block-buffered by default. Thus, in our example, the string written by  printf() is 
still in the parent’s  stdio  buffer at the time of the fork(), and this string is duplicated in 
the child. When the parent and the child later call  exit(), they both flush their copies of the stdio 
buffers, resulting in duplicate output.

We can prevent this duplicated output from occurring in one of the following ways:
	As a specific solution to the stdio  buffering issue, we can use fflush() to flush the
stdio buffer prior to a  fork() call. Alternatively, we could use  setvbuf() or setbuf()
to disable buffering on the  stdio  stream.
	Instead of calling  exit(), the child can call  _exit(), so that it doesn’t flush stdio
buffers. This technique exemplifies a more general principle: in an application that creates 
child processes, typically on ly one of the processes (most often the parent) should terminate 
via exit(), while the other processes should terminate via _exit(). This ensures that only one 
process calls exit handlers and flushes stdio buffers, which is usually desirable.

The output of the write() in the program doesn’t appear twice, because write() transfers data 
directly to a kernel  buffer, and this buffer is not dupli-cated during a  fork(). By now, the reason 
for the second strange aspect of the program’s output when redirected to a file should be clear. 
The output of  write() appears before that from printf()  because the output of write() is immediately 
transferred to the kernel buffer cache, while the output from printf() is transferred only when 
the stdio  buffers are flushed by the call to exit().

目录
打赏
0
0
0
0
5
分享
相关文章
MarS:微软开源金融市场模拟预测引擎,支持策略测试、风险管理和市场分析
MarS 是微软亚洲研究院推出的金融市场模拟预测引擎,基于生成型基础模型 LMM,支持无风险环境下的交易策略测试、风险管理和市场分析。
207 8
MarS:微软开源金融市场模拟预测引擎,支持策略测试、风险管理和市场分析
Python分支结构双分支讲解
Python分支结构双分支讲解
405 0
Matplotlib 教程 之 Matplotlib 直方图 1
使用 Matplotlib 库中的 `hist()` 方法来绘制直方图,并详细解释了其语法和各种参数的意义,如箱数 (`bins`)、值域 (`range`)、归一化 (`density`) 等。通过一个实例演示了如何创建一个简单的直方图,包括设置颜色和图表标题、坐标轴标签等属性。
140 3
在JavaEE项目中设置忽略错误(显示红叉的解决方案)
在Eclipse导入项目时, 由于当前环境的jdk或者是其他的一些原因导致出现一些不影响项目正常启动的报错(多半在JS文件中)
在JavaEE项目中设置忽略错误(显示红叉的解决方案)
阿里云域名注册流程包括域名查询和实名认证教程
阿里云域名注册包括域名查询、域名信息模板创建、域名实名认证等流程
2513 0
阿里云域名注册流程包括域名查询和实名认证教程
阿里云智能视频 AI 重装来袭,现在申领即可试用
近日,阿里云重磅推出视频点播新功能——视频AI ,基于深度学习、计算机视觉技术和海量数据,为广大用户提供多场景的视频AI服务。
4402 0
[WPF]使用WindowChrome自定义Window Style
原文:[WPF]使用WindowChrome自定义Window Style 1. 前言 做了WPF开发多年,一直未曾自己实现一个自定义Window Style,无论是《WPF编程宝典》或是各种博客都建议使用WindowStyle="None" 和 AllowsTransparency="True",于是想当然以为这样就可以了。
2204 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问