一:进程创建

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结尾