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().

目录
相关文章
|
4月前
|
C语言
exit与return的区别 exit(1)、exit(-1)和exit(0)区别
exit与return的区别 exit(1)、exit(-1)和exit(0)区别
|
4月前
|
Shell Linux Windows
从您描述的情况来看,您在执行`exit`命令后,程序立即终止了
【2月更文挑战第32天】从您描述的情况来看,您在执行`exit`命令后,程序立即终止了
23 1
|
10月前
|
IDE 开发工具 Python
python exit() sys.exit() os._exit()区别
python exit() sys.exit() os._exit()区别
36 0
|
Shell
Shell 中断与退出(continue、break、exit)
Shell 中断与退出(continue、break、exit)
204 0
|
缓存 Linux
exit() 函数和 _exit() 函数
exit() 函数和 _exit() 函数
134 0
exit() 函数和 _exit() 函数
|
物联网 Linux 开发者
进程的终止 exit|学习笔记
快速学习进程的终止 exit
106 0
|
C++
C++学习007-使用exit退出进程
使用exit可以实现退出当前进程。
198 0