Linux:进程控制之进程等待,进程替换

it2022-05-09  33

进程等待

1. 什么是进程等待?

父进程在fork出一个子进程之后,会等待子进程结束,完成一些资源回收的操作,如果不等待子进程结束,子进程就会变成僵尸进程,这样会造成内存泄漏。而父进程等待子进程结束的过程就叫进程等待。

2. 为什么要进行进程等待(进程等待的必要性)
父进程如果在fork出子进程之后,没有对子进程等待,子进程就会变成“僵尸进程”,而这样会造成内存泄漏;当进程变成僵尸进程时,指令“kill -9”也无法将僵尸进程杀死;父进程fork出子进程一定是需要子进程来执行一些动作,如果父进程不去等待子进程完成,就不能知道交给子进程的任务是否正确完成;父进程fork子进程时,会给子进程分配资源,而在子进程结束之后,子进程的资源是要父进程回收的,所以父进程要通过进程等待的方式,回收子进程资源,并获取子进程退出信息;
3. 如何进行进程等待?

进行进程等待有两种方法:

调用wait()函数; #include<sys/types.h> #include<sys/wait.h> pid_t wait( int *status); 返回值: 成功时返回子进程的进程ID;失败返回-1,同时errno被置为ECHILD; 参数: 获取子进程退出状态(也可为NULL); 调用waitpid()函数 #include<sys/types.h> #include<sys/wait.h> pid_t waitpid(pid_t pid, int *status, int options); 返回值: 当正常返回的时候返回收集到的子进程的进程ID; 如果传参时options设置为WNOHANG方式,而等待时没有已经退出的子进程可收集,返回0; 如果调用出错,则返回-1,并且将errno(错误码)设置成相应的值来指示错误; 参数: pid==-1: 等待任一个子进程; pid>0: 等待进程ID和pid值相等的进程 ; status: 获取子进程退出状态(也可为NULL); options: WNOHANG:如果pid指定的子进程没有结束,则waitpid()函数立即返回0,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号 WUNTRACED: 如果子进程进入暂停状态,则马上返回。

如何用参数status得出子进程的退出状态? 子进程的退出状态如何用参数status得出

进程替换

1. 什么是进程替换?

进程替换就是将物理内存上的一个进程的代码和数据替换成另一个需要执行进程的代码和数据,从而使进程执行不同的操作;

2.进程替换的原理?

进程替换并没有创建新的进程,替换前后的进程ID并未改变,进程替换只是用另一个新程序替换了当前进程的在物理内存上的代码段和数据段。

3.如何进行进程替换?

进行进程替换时,就需要用到exec函数簇,exec函数族是一组函数(6个)

#include <unistd.h> int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ...,char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path,char *const argv[],char *const envp[]);

在这一组函数中,只有execve()才是真正的系统调用,其它都是在此基础上经过包装的库函数; 这一组函数的特点:

哪个进程调用exec函数,哪个进程就被替换;exec函数只有出错的返回值,调用成功时没有返回值;exec函数中函数名中含有l(list)时,参数采用列表传入;函数名含有v(vector)时,参数采用数组传入;exec函数中函数名含有p(path)时,函数会自动搜索环境变量PATH;函数名中含有e(env)时,环境变量需要自己维护;

下面举组例子:

#include<stdlib.h> #include <unistd.h> int main() { char *const argv[] = {"ps", "-ef", NULL}; char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL}; execl("/bin/ps", "ps", "-ef", NULL); // 带p的,可以使用环境变量PATH,无需写全路径 execlp("ps", "ps", "-ef", NULL); // 带e的,需要自己组装环境变量 execle("ps", "ps", "-ef", NULL, envp); execv("/bin/ps", argv); // 带p的,可以使用环境变量PATH,无需写全路径 execvp("ps", argv); // 带e的,需要自己组装环境变量 execve("/bin/ps", argv, envp); exit(0); }

最新回复(0)