Linux 进程控制状态
Linux 进程控制 – 创建
在 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个_
)