相关代码
/*
*子进程空间是对父进程空间的复制(指定的内容), 子进程和父进程的进程空间是独立的, 对其中一个中的变量的修改不会影响另一个空间的相同名称的变量的值
*父进程中的缓冲区也会复制到子进程中, 所以使用设有缓冲区的标准I/O函数中的缓冲区数据也会复制给子进程
*write系统调用没有缓冲区, 只有标准I/O库里的函数会设置缓冲区
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int globvar = 0;
int main(void){
int a = 0;
pid_t pid;
char buf[] = "use write function to write sth into stdout.\n";
if(write(STDOUT_FILENO,buf,sizeof(buf)-1) < (sizeof(buf)-1)){ //write 系统调用没有缓冲区
//write error
exit(1);
}
printf("before fork.\n");
if((pid = fork()) == -1){
//fork error
}
//child
else if(pid == 0){
//change value to see its influence on parent process
a++;
globvar++;
printf("child: globvar = %d, a = %d\n",globvar,a);
exit(0);
}
//parent
sleep(2);
printf("parent: globvar = %d, a = %d\n",globvar,a);
exit(0);
}
执行结果分析
-
如果使用命令
./fork, fork
前的printf里的内容只会输出一句到标准输出, 因为标准I/O库对连接到输出设备的标准输出设置的是行缓冲, 换行符使标准输出的输出缓冲区被刷新, 所以父进程在fork子进程前中其中的缓冲区中已经没有内容 -
如果使用命令
./fork > forkres.txt
将输出重定向到文件中, fork前的printf里的内容会输出两句到文件中, 因为标准I/O库对连接到普通文件的标准输出设置的是全缓冲, 换行符不会使标准输出的输出缓冲区被刷新, 所以父进程在fork子进程前中其中的缓冲区中有内容, 所以父进程中标准输出缓冲区被复制到子进程, 在子进程和父进程退出时所有的缓冲区都会被刷新, 所以这也就是为什么printf里的内容会写两次