fork–创建进程
fork函数基本知识
pid_t fork(void)
返回值:
在父进程中,成功的话返回子进程的pid,失败返回-1
在子进程中,返回值pid为0
fork()函数将运行着的进程分裂出另一个子进程,它通过拷贝父进程的方式创建子进程。
子进程与父进程有相同的代码空间、文件描述符等资源 ,如下图所示:
父、子进程的区别:
fork的返回值不一样,pid不同,ppid不同,未决信号集合文件锁不继承,资源利用量清0
进程创建后,子进程与父进程开始并发执行,谁先执行由内核调度算法来决定。
init进程:pid为1,所有进程的祖先。
代码示例
看下面的代码,观察父、子进程打印的结果
fork1.c
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
//定义pid号
pid_t pid;
printf("[%d]:Begin!\n",getpid());
//在调用fork前,调用!!!!
//fflush(NULL);
pid = fork();
if(pid < 0)
{
perror("fork()");
exit(1);
}
if(pid == 0) //child
{
printf("[%d]:Child is working!\n",getpid());
}
else //parent
{
printf("[%d]:Parent is working!\n",getpid());
}
printf("[%d]:End!\n",getpid());
return 0;
}
编译执行程序,父子进程的pid分别是9227和9228,如下图
重新开启一个终端,使用如下命令,显示进程的关系
ps axf
从上图看出,(pid=9227)./fork1的进程创建了一个(pid=9228)的进程./fork1。(pid=9227)./fork1进程的父进程是bash,即上图中pid=8760
父、子进程的输出
输出到终端
我们重新编译代码,执行,输出的内容中,Begin!输出1次,见下图:
输出到文件
执行程序的将输出重定向一个文件中,查看文件的内容,发现Begin!内容输出了2次
同样一份代码,为何输出的内容有差异那?
是缓冲造成的。 终端是标准输出设备, 是行缓冲模式 ,printf语句中的\n
是行缓冲作用,所以\n会刷新缓冲区。 如果重定向到文件, 文件的缓冲是全缓冲模式 ,\n
就起不到刷新缓冲的作用,只是一个换行的作用
Begin!放到缓冲区中,还没来得及写到文件里面的时候,马上执行了fork函数,父、子进程的缓冲区各自有begin,所以会有两个。
如何解决,上面的问题
要在调用fork函数前,调用fflush(NULL)
函数。