目录
- 进程替换基础知识
- 什么是进程替换
- 进程替换函数
- 函数使用
- execl
- execlp
- execle
- execv
- execvp
- execve
进程替换基础知识
什么是进程替换
进程替换:把当前进程换为其他进程执行。(其他进程:创建新进程,生成可执行程序,装在进内存)进程替换替换的是进程实体。PCB使用以前的只是修改。
进程替换函数
头文件:#include<unistd.h>
exec系例函数:
函数 | 参数 |
---|---|
execl | int execl(const char* path, const char * arg,…); |
execlp | int execlp(const char* file, const char * arg,…); |
execle | int execle(const char* path, const char * arg,…,char* const envp[]); |
execv | int execv(const char * path, char* const argv[]); |
execvp | int execvp(const char * file, char* const argv[]); |
execve | int execve(const char * path, char* const argv[],char* const envp[]); |
参数讲解:*path:新替换的程序的路径名称
*arg:传给新程序主函数的第一个参数,一般是程序的名字
arg后面的参数列表,参数个数变化,但是最后一个是参数必须是空指针。
envp[]:环境变量
argv[]:将argv以及后面的参数整合成的数组。
函数返回值:此处函数虽然返回值是int,但是如果函数运行成功是没有返回值的,没有返回值就不会运行后续代码。
函数使用
execl
代码举例:
int main(){
pid_t pid=fork();
if(pid==0){
execl("/usr/bin/ls","ls","--color",(char*)0);
//execl("./main","./main",(char*)0);
perror("exec error: ");
}else{
wait(NULL);
sleep(5);
peintf("parent run\n");
}
}
以上代码段中”–color“意为使结果有颜色,我们使用的ls命令其实默认后面又–color,比如ps -ef ,'-‘后面内容解析每一个字符含义,’–'后面解析每一个单词。perror(“error:”);该函数和输出函数是一样的,唯一不同的是此处如果出现错误才会输出,并且输出的是错误原因。wait函数获取子进程的退出码,阻塞父进程,等待子进程结束才会运行父进程。
我们此处讲述execl函数,参数依次是执行的命令的路径,命令名字,参数,结束标志。第二个execl函数是执行我们的main函数。
execlp
int main(){
pid_t pid=fork();
if(pid==0){
execlp("ps","ps","-f",(char*)0);
perror("exec error:");
}else{
wait(NULL);
sleep(5);
printf("parent run..");
}
}
此处ps我们不需要给路径,此处P指的是PATH系统给定的路径,如何查看系统环境呢?
此处我们通过export 变量名=值(export PATH=$PATH:.)在系统变量中加入了我们当前路径’.'。删除刚添加的系统变量只需要将原来的环境变量重新赋值即可。
运行结果:
execle
int main(int argc,char* argv[],char* envp[]){
pid_t pid=fork();
if(pid==0){
execle("./main","./main",(char*)0,envp);
perror("error: ");
}else{
wait(NULL);
sleep(5);
printf("parents..");
}
}
e指的是环境变量
注意此处环境变量使用envp时必须在main函数中加入参数,这个环境变量是从当前main所在的进程的父进程继承下来的。
execv
int main(){
pid_t pid=fork();
if(pid==0){
char* buff[]={"ps","-f",(char*)0}
execv("/usr/bin/ps",buff);
perror("exec error:");
}else{
wait(NULL);
sleep(5);
printf("parent run..");
}
}
同上execl函数不同之处在于将参数放入一个数组中即可。
execvp
int main(){
pid_t pid=fork();
if(pid==0){
char *buff[]={"ps","-f",(char*)0};
execvp("ps",buff);
perror("exec error:");
}else{
wait(NULL);
sleep(5);
printf("parent run..");
}
}
execve
int main(int argc,char* argv[],char* envp[]){
pid_t pid=fork();
if(pid==0){
char* buff[]={"./main",(char*)0}
execle("./main",buff,envp);
perror("error: ");
}else{
wait(NULL);
sleep(5);
printf("parents..");
}
}