以下全都是用vfork!!!
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int
glob = 5;
int
main()
{
int
var=10;
pid_t pid;
printf
(
"befork vforkn"
);
if
((pid = vfork()) < 0)
{
printf
(
"errorn"
);
exit
(1);
}
else
if
(pid == 0)
{
glob++;
var++;
_exit(0);
}
printf
(
"pid = %d, glob = %d, var = %d"
,getpid(), glob,var);
_exit(0);
}
编译:gcc -g -o example1 example1.c后
./example1
输出:before vfork
因为_exit(0)不进行任何处理直接退出。且是因为终端是行缓冲,则只有输出before vfork。
./example1 > output_example1
cat output_wxample1
输出:无
因为_exit(0)不进行任何处理直接退出。是重定向是全缓冲,则什么都没有输出。
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int
glob = 5;
int
main()
{
int
var=10;
pid_t pid;
printf
(
"befork vforkn"
);
if
((pid = vfork()) < 0)
{
printf
(
"errorn"
);
exit
(1);
}
else
if
(pid == 0)
{
glob++;
var++;
exit
(0);
}
printf
(
"pid = %d, glob = %d, var = %d"
,getpid(), glob,var);
exit
(0);
}
编译:gcc -g -o example2 example2.c后
./example2
输出:before vfork
pid=xxxxx,glob=6,var=11.
因为子进程中
exit
(0)进行刷新缓冲,且将glob=6,var=11写如磁盘,还有其它的一些如关闭所有I/O流的处理再退出。且父进程有
exit
(0),所以输出上面的结果。
./example2 > output_example2
cat output_example2
输出:同上。
因为重重定向,是全缓冲,且父子进程都有
exit
(0),所以输出的结果同上。
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int
glob = 5;
int
main()
{
int
var=10;
pid_t pid;
printf
(
"befork vforkn"
);
if
((pid = vfork()) < 0)
{
printf
(
"errorn"
);
exit
(1);
}
else
if
(pid == 0)
{
glob++;
var++;
_exit(0);
}
printf
(
"pid = %d, glob = %d, var = %d"
,getpid(), glob,var);
exit
(0);
}
编译:gcc -g -o example4 example4.c后
./example3
输出:before vfork
pid=xxxxx,glob=6,var=11.
因为子进程有_exit(0)不进行刷新缓冲,但是还是改变了glob与var的值,且glob=6,var=11,然后子进程结束了。然后再执行父进程中的
printf
,最后执行
exit
(0),写入磁盘与清除缓冲,关闭I/O流,则输出上面的第二行。所以输出上面的结果。
./example3 > output_example3
输出:同上
因为重定向是全缓冲的,子进程修改,glob的值与var的值,使得glob=6,var=11,因为子进程中有_exit(0),所以子进程改变了值就退出程序了。然后父进程遇到
exit
(0)就将数据写到磁盘。因而结果也是上面的。
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int
glob = 5;
int
main()
{
int
var=10;
pid_t pid;
printf
(
"befork vforkn"
);
if
((pid = vfork()) < 0)
{
printf
(
"errorn"
);
exit
(1);
}
else
if
(pid == 0)
{
glob++;
var++;
exit
(0);
}
printf
(
"pid = %d, glob = %d, var = %d"
,getpid(), glob,var);
_exit(0);
}
编译:gcc -g -o example4 example4.c后
./example4
输出:before vfork
pid=xxxxx,glob=6,var=11.
这个输出比较特殊,照理论来讲,上面的输出的第二行是不应该输出的。但是见下面,按照APUE的说法,现代大部分实现都把IO流的关闭交给内核。再看标准,_exit对流的刷新或关闭也是实现相关的。
则 自己的linux系统 man _exit 则如下:
DESCRIPTION
.......The function _Exit() is equivalent to _exit().
RETURN VALUE
These functions
do
not
return
.
CONFORMING TO
SVr4, POSIX.1-2001, 4.3BSD. The function _Exit() was introduced by C99.
NOTES
.......Whether it flushes standard I/O buffers and removes temporary files created with
tmpfile
(3) is implementation dependent. ...........Whether any pending I/O is cancelled, and which pending I/O may be cancelled upon _exit(), is implementation-dependent.
SEE ALSO execve(2), exit_group(2), fork(2), kill(2), wait(2), wait4(2), waitpid(2),
atexit
(3),
exit
(3), on_exit(3), termios(3)
Linux 2001-11-17 _EXIT(2)
_exit(0),是否刷新标准I/O是依据现实的,而未决的I/O的关闭也是依据现实的。
也就可否理解为:_exit(0)上面的
printf
输出,有时有,有时无,依据内核自身处理来决定。
./example4 > output_example4
输出:同上
理由大概同上的。