目录
替换原理
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
当进程程序替换时,有没有创建新的进程?
进程程序替换之后,该进程对应的PCB,进程地址空间以及页表等数据结构都没有发生改变,所以并没有创建新的进程,而且进程程序替换前后该进程的pid并没有改变
子进程进行进程程序替换后,会影响父进程的代码和数据吗?
子进程刚被创建时与父进程共享代码和数据,但当子进程需要进行进程程序替换的时,也就意味着子进程需要对其数据和代码进行写入操作,这时就需要将父子进程共享的代码和数据进行写时拷贝,此后父子进程的代码和数据也就分离了,因此子进程进行程序替换后不会影响父进程的代码和数据
替换函数
替换函数有六种以exec开头的函数,它们统称exec函数:
一. int execl(const char *pathname, const char *arg, ...);
第一个参数是要执行程序的路径
第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾
例如,要执行的程序是ls程序
execl("/usr/bin/ls", "ls", "-l", "-a", NULL);
二. int execlp(const char *file, const char *arg, ...);
第一个参数是执行程序的名字
第二个参数是可变参数列表,表示你要如何执行这个程序,使用NULL结尾
例如,要执行的程序是ls程序
execlp("ls", "ls", "-l", "-a", NULL);
三. int execle(const char *pathname, const char *arg, ...);
第一个参数是要执行参数的路径
第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾,第三个参数是你自己设置的环境变量、
例如:你设置了MYVAL环境变量,在mycmd程序内部就可以使用该环境变量
char* myenvp[] = { "MYVAL=2021", NULL };
execle("/usr/bin/ls", "ls", "-l", "-a", NULL, myenvp);