前言
进程的替换目的是为了节省资源,假设现在又A、B、C三个应用程序需要执行,如果我每执行一个程序都创建一个进程,目的是可以实现的,但是会浪费资源,那么可以创建一个进程,然后让进程在一个进程进行替换,那么就可以避免创建过多的进程导致资源的浪费。
一、exec函数族
int execl(const char *pathname, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, .../* (char *) NULL */);
int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[] */);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
参数说明:
path:可执行文件的路径名,一般的可执行程序是在/bin目录下,例如常用的/bin/ls,/bin/pwd等。
file:可执行文件名,可以通过PATH环境变量指定的路径,只需传入"ls","cd"等。
arg:参数列表,以NULL结尾
argv[]:参数数组
envp[]:环境变量数组,环境变量为空,则新程序通常会继承调用进程的环境变量。
...代表一个可变参数;注释 /* (char *) NULL */ 是对程序员的提示,意思是结束标识为一个空指针。
返回值:
exec()函数只在发生错误时返回。返回值为-1,errno表示错误。
这些函数在执行时不会创建新的进程,而是替换调用它们的进程的映像。如果exec()调用成功,当前进程的代码、数据和堆栈将被新程序的相应部分替换,并且控制权立即转交给新程序,就是说exec()函数下的代码不会执行;使用exec()函数族可以进行进程替换,这是进程生命周期管理的一种方式,允许进程在执行新程序时重用现有的资源。
二、使用示例
1.execvp函数替换ls -l命令
代码如下(示例):
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int num = 0;
char buf[32];
printf("请输入一个命令:");
fgets(buf,sizeof(buf)-1,stdin);//使用fgets将输入的命令存储在buf数组中;
buf[strlen(buf)-1] = '\0';
int pid = fork();//创建子进程;
if(pid == -1){
perror("fork:");
exit(EXIT_FAILURE);
}else if(pid == 0){
char *p_cmd = strtok(buf," ");//使用分割字符串函数将命令分割开,并将每隔字符串地址保存在指针数组p中;
char *p[10];//定义一个指针数组用来存放分割开的字符串;
p[num] = p_cmd;
num++;
while((p_cmd = strtok(NULL," ")) != NULL){
p[num] = p_cmd;
num++;
}
p[num] = NULL;//将字符串后的指针指向空;
int exec = execvp("ls",p);//如果进程被替换,WEXITSTATUS(status)=0(退出的状态),并且下面的代码将不会执行;
if(exec == -1){
perror("execvp\n");
}
printf("child end!\n");
exit(EXIT_FAILURE);//WEXITSTATUS(status)=1
}else{ //主进程;
int status;
int w = waitpid(pid,&status,0);//阻塞主进程,等待子进程结束;
if(w == -1){
perror("waitpid:\n");
exit(EXIT_FAILURE);
}
printf("WEXITSTATUS(status) = %d\n",WEXITSTATUS(status));
if(WEXITSTATUS(status)){
printf("Replace failure\n");
}else{
printf("Replace success\n");//如果被替换,执行替换后的代码;
}
}
}
WEXTSTATUS(status)内部内部实际是
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
一个宏函数(不了解的话,可以看我发的c语言中的宏),执行了一个按位与和右移8位的操作.

如果我们的进程被替换,该宏 得到的就会是0x00,也就是0,所以主进程中的if 的条件为假,打印的结果就会使replace success,当然还有进程替换执行的ls -l命令。
运行结果:
上面是代码执行的结果,下面是在终端执行的ls -l 命令。
这里我只是写了ls -l的命令,当然还可以替换很多命令。
1629

被折叠的 条评论
为什么被折叠?



