在 Linux 中,进程控制有四种状态:创建、退出、等待、替换。
其中还涉及了 阻塞 与 非阻塞 两种情况,即
阻塞:为了完成一个功能,发起一个调用,若功能完成条件不具备,一直等待
非阻塞:为了完成一个功能,发起一个调用,若功能完成条件不具备,立即报错返回
该篇博客将解释 创建 状态中所涉及的两个函数:
1、fork()
pid_t fork(void)
此函数为 创建进程的接口 。通过复制调用这个接口的进程(父进程),创建一个新的进程(子进程)。其中父子进程代码共享,但数据独有。
返回值:成功则父进程返回子进程的 pid ,其值大于0,子进程返回0;出错返回-1
2、vfork()
pid_t vfork(void)
创建一个子进程并阻塞父进程;父子进程共用虚拟地址空间,所以先阻塞父进程让子进程运行父子进程共用栈区,如果同时运行就会造成栈混乱 ,因此vfork阻塞父进程,让子进程先运行,直到子进程exit退出或程序替换后,父进程运行。
此程序创建的子进程在 主函数main() 中不能用return退出,因为return退出时会释放资源,这些资源中包含父进程的资源,若直接用return退出,很有可能会导致父进程出问题!!!!
返回值:成功则父进程返回子进程的 pid ,其值大于0,子进程返回0;出错返回-1
附上两道题:
1、题:下列程序共创建了几个子进程
int main() //父进程,为方便表示,定为0号进程,以下同理
{
fork();//一个fork()后,成功则会创建一个子进程,1号
fork() && fork()||fork();// 2 3 4号(与程序中的fork()对应)
fork();//5号
}
解:上述程序运行结束后,会新创建19个子进程。解析如下:
2、题:下列程序中打印了多少次字符 _
int main(int argc,char *argv[])
{
int i;
for(i=0;i<2;i++)
{
fork();
printf("_");//此处没有换行符,即数据没有刷新,运行结果存于缓冲区
}
}
解: 解析如下:
第一次运行时:会产生一个子进程,即有两个进程,都会打印 _,即该两个进程的各自缓冲区中都有一个 _
第二次运行时:上述两个进程又各自产生了一个子进程(该子进程复制了其父进程的内容,包括缓冲区中的一个_),即此时有四个进程,且该四个进程都会打印_,即他们各自的缓冲区中都有两个 _。因此最终结果为8个 _。
(如果有换行符,则第一次运行后,新开辟的两个子进程缓冲区中就没有一开始的 _,最后运行下来是6个_)



