在 Linux
中,进程控制有四种状态:创建、退出、等待、替换。
本篇博客讲述 替换 状态下的一些事:
程序替换:替换一个进程正在调度运行的程序。替换之后,程序是从头重新运行,加载一个新的程序到内存中,更新当前进程的页表映射信息到新的程序上。
程序替换是在当前进程pcb
并不退出的情况下,替换当前进程正在运行的程序为新的程序,即
1、程序替换成功后,运行完新程序,依然会运行原有的代码
2、程序替换成功后,原进程没有退出,使用原进程运行新程序
如:
vi
或 vim
编辑器下,在文件的底行输入:12s/argv/environ/g
,即将12行的argv
全部替换为environ
,该程序中的g
代表全部
exec
函数族:5个库函数 + 系统调用接口(其实是6个库函数,但最后一个基本不怎么用)
注:该函数族中的函数使用时,均需包含头文件 unistd.h
,即 #include <unistd.h>
5个库函数:(除了带p的,其他的函数都得给路径)
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 execvpe(const char *file, char *const argv[], char *const envp[]);
系统调用接口:
int execve(const char *path, char *const argv[], char *const envp[]);
上述函数,总体有三类参数:(参数总是以NULL结尾)
(1)新的程序路径名称:path
(需要带路径)或 file
(可以直接为文件名)
(2)程序运行参数:arg
或 argv
(3)自己设定环境变量(上述函数中最后一个字母为e
的,需要自设环境变量;其他函数是调用系统自身的环境变量)
注意:参数是以NULL结尾,在NULL之后才是其他
1、execl
和 execv
的区别:程序运行参数的不同设置方式(execl
是参数一个一个给,execv
是所有参数用指针直接给),如:
execl("/bin/ls","ls","-a","-l",NULL);//参数的给与,首先是它自己,其次是与其相关的,且是以NULL结尾
char *argv[]={"ls","-a","-l",NULL};execv("/bin/ls",argv);
2、execl
和 execlp
的区别:新的程序是否需要带路径(execl需要带路径,execlp不需要带),如:
execl("/bin/ls",...);
execlp("ls",...);
不用带路径的前提是:会到PATH
环境变量指定的路径下去找对应程序,如果该指定路径下无对应路径,则程序就会出错,或自己指定路径也可以
3、excel
和 execle
的区别:环境变量是否由自己来设置,如何退出进程
execl("/bin/ls",...); // 使用默认当前就有的环境变量
char *env[]={"MYVAL=1000",NULL}; execle("/bin/ls",...,NULL,env); // 使用自设的环境变量
为验证以上函数的使用,给出几个例子:
注:下列程序中 myenv
是一个输出 上述函数族中函数对应的 程序运行参数 和 所设定变量 的执行文件。
例1:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
printf("进行程序替换!!\n");
// execl("/usr/bin/ls","ls","-a","-l",NULL);//当该语句运行完后,程序就会开始运行ls,而非继续往下运行原程序
//该语句和上行程序作用一致
//char *arg[]={"ls","-a","-l",NULL};
// execv("/usr/bin/ls",arg);
char *arg[]={"ls","-a","-l",NULL};
//execvp("ls",arg); // 不需要带路径
execvp("./myenv",arg);//如果所替换程序未在PATH指定路径下,可以直接自定义路径
printf("程序替换完毕!!\n");
return 0;
}
如果程序最后输出 程序替换完毕!! 则说明程序替换未成功,即该程序未实现目标功能
例2:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
printf("进行程序替换!!\n");
char *arg[]={"ls","-a","-l",NULL};
char *env[]={"MYVAL=1000",NULL};//自设环境变量
execve("./myenv",arg,env);
printf("程序替换完毕!!\n");
return 0;
}
运行结果为:
进行程序替换!!
argv[0]=ls
argv[1]=-a
argv[2]=-l
environ[0]=MYVAL=1000
例3:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
printf("进行程序替换!!\n");
char *arg[]={"ls","-a","-l",NULL};
char *env[]={"MYVAL=1000",NULL};//自设环境变量
execle("./myenv","myenv","-a","-l",NULL,env);
printf("程序替换完毕!!\n");
return 0;
}
运行结果为:
进行程序替换!!
argv[0]=myenv
argv[1]=-a
argv[2]=-l
environ[0]=MYVAL=1000