转载来自CSDN:https://blog.csdn.net/weixin_43580319/article/details/115482494

1. 进程等待的非阻塞模式

1.1 非阻塞模式

1.WNONHANG
2.搭配循环使用
  循环判断条件:waitpid函数的返回值
    0:表示没有等到
    子进程的PID:表示等到了

2. 进程程序替换

2.1 作用

  将正在运行的进程,替换成为另外一个程序,运行另外一个程序的代码。
在这里插入图片描述

2.2 原理

  进程程序替换就是将进程的代码段,数据段替换成为新的程序的代码段和数据段,更新堆栈信息。

2.3 应用场景

2.3.1 守护进程

在这里插入图片描述
  守护进程本质上是为了提供7*24小时的服务,服务不间断,但是,当子进程由于代码崩溃退出之后,虽然父进程会立即重新启动一个子进程,让子进程进行程序替换,这块我们需要注意,导致子进程退出的原因是崩溃,而崩溃的代码并没有修复。

2.3.2 bash(命令行解释器)

2.4 接口

2.4.1 exec函数簇

1.int execl(const char *path,const char * arg,…);
  path:带路径的可执行程序(路径+可执行程序名称)
  arg:给待要替换的可执行程序传递参数
规定:
  1.第一个参数是可执行程序本身
  2.多个可执行参数,使用‘,’进行间隔
  3.参数的最后需要以NULL结尾
  …:可变参数列表
返回值:
  替换成功之后,该函数是没有返回值,也不知道返回值给谁,进程的PID和替换之前进程的PID一样,只有替换失败之后,才会有返回值,返回值小于0。

2.int execlp(const char *file, const char *arg,…);
参数:
  file:只需要传递待替换的可执行程序
注意:
  1.如果只传递可执行程序的名称,则该可执行程序一定要在环境变量PATH当中可以找到。
  2.也可以将待替换的可执行程序的路径写全
  arg:同execl
  函数名带有‘p’,则表示当前函数会自动搜索环境变量PATH

3.int execle(const char path, const char * arg, …, char * const envp[]);
  path:带有路径的可执行程序
  arg:同execl
  envp[]:指针数组,本质上是数组,数组的每个元素都是一个
char
,程序员需要自己组织环境变量,放到envp[]数组当中,最后一个元素需要放入NULL。

  函数名称带有‘e’:则表示当前的execl函数,需要自己组织环境变量,放到envp指针数组当中,以NULL结尾。

  函数名带有‘l’:表示给待替换的可执行程序,传递的命令行参数为可变参数列表。

4.int execv(const char *path,char *const argv[]);
  path:带有路径的可执行程序
  argv[]:指针数组
  命令行参数的数组,存放的是传递给可执行程序的命令行参数
规则:
1.第一个参数是可执行程序本身
2.参数的最后需要以NULL结尾

  函数名当中带有‘v’:表示给待替换的可执行程序传递的命令行参数为指针数组
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);

验证方式:
  1.直接替换命令程序
  2.替换自己写的程序
    2.1验证PID是否变哈
    2.2验证环境变量

在这里插入图片描述

3. minishell

  1.创建子进程
  2.父进程需要进行进程等待
  3.子进程进行进程程序替换成为命令程序
考虑:
  父进程需要进行循环
  子进程
  ls -a -l
  区分命令程序和命令行参数
  进程程序替换
  execvp

在这里插入图片描述