进程控制

1.进程创建:

(1) 分配新的内存块和内核数据结构给子进程
(2)将父进程部分数据结构内容拷贝至子进程
(3)添加子进程到系统进程列表当中
(4)fork返回,开始调度器调度

创建子进程除了fork还有vfork:
pid_t vfork(void);
(1)vfork用于创建一个子进程,而子进程和父进程共享地址空间,fork的子进程具有独立地址空间。
(2)vfork保证子进程先运行,在它调用exec或exit(return不行)之后父进程才可能被调度运行。vfork也有两个返回值。
注意:在任何一个系统上实现的vfork都有问题,所以不要用vfork
就算是fork实现了写时拷贝,也没有vfork高效

2.进程等待(子必须被等待)

进程等待的必要性:
(1)子进程退出,父进程不管不顾,就可能造成“僵尸进程”的问题,进而造成内存泄露。
(2)我们需要知道父进程派给子进程的任务完成情况,如,子进程运行完成,结果是对还是不对,或者是否正常退出。
(3)父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息。

等待方法:
(1)pid_t wait(int *status);//父进程调用,返回被回收的子进程pid,属于系统调用,参数是子进程的退出信息,如果传NULL,表示不关心退出信息。但是父进程怎么拿到的?每个进程的信息都是独立的,因为这是系统调用,系统拿到后放在status。status只关心低16位,其中低7位表示信号状态(判断是否为异常退出,如果是,那么退出码表示的退出信息就没有意义),次低8位,表示退出码,返回值若为-1表示等待失败
注:wait可以回收僵尸进程,但是只能回收一个。
需要了解的宏:
WIFEXITED(STATUS):如果正常退出,返回真。
WEXITSTATUS(status):得到子进程退出码。
WIFSIGNALED(status):如果是信号搞死,返回真。
WIERMSIG(status):获得搞死该进程的信号。

(2) pid_t waitpid(pid_t pid, int *status, int options);//第一个参数为要等待的子进程id,如果是-1,表示等待任意子进程,。第三个参数默认为0.waitpid也可以回收僵尸进程。
参数pid:

0:等待进程id为pid的子进程死亡。
=0:调用者所在进程组的任何一个子进程
= -1:任何一个子进程。
<-1:|pid|进程组的任何一个子进程。
参数options:
WNOHANG 如果没有子进程死亡,直接返回,返回值为0.

阻塞式等待:因为条件不成熟,“我“什么事也不能做,卡在这里,只能等条件成熟,才能干别的事情。
非阻塞式等待:因为条件不成熟,并没有将我“卡住”,

3进程终止:

(1)代码跑完,结果正确
(2)代码跑完,结果不正确
(3)代码没跑完,异常终止(while(1)永远跑不完,只能ctrl c 终止,abork,kill pid)

echo $?查看进程退出码,只保存离他最近的进程退出码。
return只有在main函数中才会退出进程,参数表示退出码,而exit()在任何时候使用都会退出进程,参数表示退出码,退出码表示进程退出信息。
除了exit可以退出进程,_exit也可以,但是_exit是强制退出,而exit退出进程时还会做一些收尾工作,像刷新缓冲区。
这里写图片描述

4.进程替换:

想想在一个shell终端,我们敲下ls命令后,ls命令是怎样被执行的呢,我们很容易想到,ls的代码开始肯定在磁盘上,那么它是如何加载到内存上然后被执行呢?这里就用到了进程替换。
如果shell直接将ls的代码替换他自己,那么如果ls执行失败他自己也会崩掉,所以它一定是用fork()创建了一个子进程,自己就执行原代码,让ls的代码将子进程的代码替换,子进程执行ls的代码。
注:进程替换并没有创建新进程,所以PID不变
int execvp( const char *file, char *const argv[]);
这里写图片描述

execvp第一个参数为替换文件,第二个参数为main函数的命令行参数,第一个是替换进程的可执行程序名,必须以NULL结尾
这里写图片描述

因为是程序替换,替换之后就直接去执行替换后的代码,回不到原代码了。

小案列:

(1)mysystem
这里写图片描述
这里写图片描述
这里写图片描述

这里就是先用fork创建子进程,子进程用execvp进程替换,父进程用waitpid阻塞等待子进程。
(2)myshell
这里写图片描述
这里写图片描述
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值