创建进程
进程控制原语
fork函数
pid_t fork(void); //创建一个子进程
【返回值】有两个 一个进程 --> 两个进程 --> 各自对fork做返回
- 返回子进程的pid(非负整数 > 0) (父进程)
- 返回0 (子进程)
创建单个子进程
【练习】
#include <stdio.h>
#include <unistd.h>
//创建单个子进程
int main()
{
pid_t pid;
printf("XXXXXXXXXXXXXXXXXX\n");
pid = fork();
if(pid == 0) //子进程
{
printf("I'm child, pid = %u, ppid = %u\n", getpid(), getppid());
}
else if(pid > 0)
{
sleep(1);
printf("I'm parent, pid = %u, ppid = %u\n", getpid(), getppid());
}
else
{
return -1;
}
printf("YYYYYYYYYYYYYYYYYYYYYYY\n");
return 0;
}
【运行结果】
循环创建N子进程
【代码】
#include <stdio.h>
#include <unistd.h>
//循环创建多个子进程
int main()
{
pid_t pid;
printf("XXXXXXXXXXXXXXXXXX\n");
int n = 3;
int i;
for(i = 0; i < n; i++)
{
pid = fork();
if(pid == 0) //子进程
{
printf("I am %d child, pid = %u\n", i + 1, getpid());
}
else if(pid > 0)//父进程
{
sleep(1); //让子进程先输出
printf("I am %d parent, pid = %u\n", i + 1, getpid());
}
}
return 0;
}
【运行结果】
【分析结果】从结果上看,远远不止创建了3个子进程
简单想,for(i = 0; i < n; i++){ fork(); }即可。但是这样创建的是N个子进程吗?
【图解】
【修改代码】父进程负责fork,子进程什么也不做
#include <stdio.h>
#include <unistd.h>
//循环创建多个子进程
int main()
{
pid_t pid;
printf("XXXXXXXXXXXXXXXXXX\n");
int n = 3;
int i;
for(i = 0; i < n; i++)
{
//父进程负责fork,子进程什么也不做
pid = fork();
if(pid == 0) //子进程通过break
{
break;
}
}
if(i < n)
{
sleep(i); // i = 0,1,2…… //保证子进程按找顺序输出
printf("I am %d child, pid = %u\n", i + 1, getpid());
}
else //i = n
{
sleep(i); //保证子进程先输出,父进程先睡眠 n 秒
printf("I am parent\n");
}
return 0;
}
【运行结果】
上面的代码中,我们用sleep函数保证了子进程的顺序输出,并且父进程在所有子进程运行结束之后再运行。试想一下,当我们去掉所有sleep函数之后,运行结果会和上面一致吗?
此时你会发现结果完全不同,最后程序像还没有结束一样,一直有光标在最后一行闪。当我们在光标处输入ls命令,发现ls命令可以正常执行。当执行完ls之后,shell回到了正常的状态
那么为什么会出现这样的执行结果呢?
【光标问题】
【关键】shell进程(父进程的父进程)搅和进来。当我去掉所有的sleep函数之后,父进程和子进程以及shell进程之间共同抢夺CPU,shell进程并不知道父进程又创建了子进程
shell的正常状态,阻塞在这里等待用户输入,接受命令解析
当我输入一个 ./a.out,就是要把当前程序运行,这时shell进程会把自己切到后台去,把前台(终端)交给 a.out这个进程
那shell进程什么时候收回前台的使用权?a.out运行结束
那shell进程怎么判断a.out结束了呢?a.out只要return了,shell进程就要抢占前台,然后在进入到正常状态,等待用户输入
但是shell进程不知道还有子进程,当父进程执行完(打印了 I am parent),shell进程抢占了前台,恢复到正常状态,此时子进程3用了终端,所以这句话( I am 3 child, pid = 19810)就没打印到下一行的行首,而是直接打印到光标的后面的位置上,打印完之后,做了个换行,光标移到下一行起始位置,这时候子进程2又抢占了终端,在光标之后打印了一句话……
当3个子进程打印结束后,光标停在子进程1打印结束的下一行行首,等待用户输入
所以我们第一加了sleep函数保证父进程在所有子进程结束之后再退出,所以shell是正常的状态,不会出现上面的情况
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_41033011/article/details/107480456