一:进程创建
fork()函数:
#include
pid_t fork(void)
进程调用fork,将控制转移到内核的fork代码后,内核做:
1.分配新的内存块和内核数据内容拷贝给子进程
2.将父进程部分数据内容拷贝给子进程
3.添加子进程到系统进程列表当中
4.fork返回,开始调度器调度
返回值:
子进程返回0,父进程返回子进程id,出错返回1
写时拷贝:
通常,父子代码共享,父子再不写入时,数据总是共享的,当任意一方试图写入时,以写时拷贝的方式各自一份副本
原因:减少子进程成本,减少内存浪费
fork调用失败的原因:
系统中有太多进程
实际用户的进程超过了限制
二.进程终止
本质:释放系统资源,就是释放进程申请的相关内核数据结构和对应数据和代码
进程退出场景:
1.代码运行完毕,结果正确
2.代码运行完毕,结果不正确
3.代码异常终止
退出码:


一可以使用strerror(i)取打印
进程一段出现异常,退出码就没有意义了
exit(int status):表示进程结束,进程终止 status:退出码
三.进程等待:
进程等待的必要性:
1.子进程退出,父进程不管不顾,会造成僵尸进程的问题,从而造成内存泄露
2.我们需要知道子进程的完成的情况
3.父进程通过进程等待的方式回收子进程资源
wait的使用:
#include
#include
#include
#include
using namespace std;
int main(){
pid_t id=fork();
if(id==0)
{
int cnt=5;
while(cnt){
cout<<"子进程"<<" "<0){
cout<<"sucessful"<<" "<
等待成功返回子进程id 失败-1
WEXISTATUS(status)&status:返回退出码

options:WNOHANG(非阻塞调用)
此时返回值有三种:pid>0:等待结束
pid=0:调用结束,但子进程没有退出
pid:失败
四.进程的程序替换
1.替换原理:
⽤fork创建⼦进程后执⾏的是和⽗进程相同的程序(但有可能执⾏不同的代码分⽀),⼦进程往往要调⽤⼀种 exec 函数以执⾏另⼀个程序。当进程调⽤⼀种 exec函数时,该进程的⽤⼾空间代码和数据完全被新程序代替,从新程序的启动例程开始执行。调⽤exec并不创建新进程,所以调⽤exec前后该进程的 id 并未改变。


如以上代码当执行到execl时下面代码会直接被execl直接替换。
只有发生失败时会出现返回值-1,其余都不会有返回值
下面是exec函数总结:

1.int execl(const char*path,const char*arg,...):路径+程序名+参数
注意:必须要以NULL结尾表示传参结束
2.int execlp(const char*file,const char*arg,...):程序名+参数
注意:是在环境变量里面查找
3.int execlp(const charpath,char*const argv[]):路径+加参数数组
注意:也必须以NULL结尾
评论
还没有任何评论,你来说两句吧!