linux中进程的替换

前言

进程的替换目的是为了节省资源,假设现在又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的命令,当然还可以替换很多命令。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值