当前位置: 首页 > news >正文

进程程序替换-Linux

文章目录

  • 替换原理
  • 替换函数
  • 函数解释

替换原理

  • 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
    在这里插入图片描述

替换函数

  • 其实有六种以exec开头的函数,统称exec函数:

#include <unistd.h>`
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 execve(const char *path, char *const argv[], char *const envp[]);

在这里插入图片描述
上图这几种的本质是调用下图的
在这里插入图片描述

函数解释

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
  • 如果调用出错则返回-1。
  • 所以exec函数只有出错的返回值而没有成功的返回值。
    命名理解:
  • 这些函数原型看起来很容易混,但只要掌握了规律就很好记。
    • l(list) : 表示参数采用列表
    • v(vector) : 参数用数组
    • p(path) : 有p自动搜索环境变量PATH
    • e(env) : 表示自己维护环境变量
      在这里插入图片描述

exec调用举例如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/types.h>

#define NUM 16

const char* myfile="./mycmd"; //调用自己写的

int main(int argc, char* argv[], char* env[])
{
  pid_t id = fork();
  
  char* const _env[NUM]={
    (char*)"MY_PATH_VAL=888777666555",//自己的环境变量名称
    NULL
  };

  if(id<0){perror("fork"); exit(1); }
  else if(id==0){
    //child
    printf("子进程开始!!!\n");
    sleep(3);
    char* const _argv[NUM]={
        (char*)"ls",
        (char*)"-a",
        (char*)"-l",
        (char*)"-i",
        NULL
    };
    //execl("/usr/bin/ls", "ls", "-l", "-a", NULL);
    //execv("/usr/bin/ls", _argv);
    //execlp("ls", "ls", "-l", "-a", NULL);
    //execvp("ls", _argv);
    execle(myfile, "mycmd", "-a", NULL, _env);

    printf("子进程退出!!!\n");
    exit(1);
  }
  else{
    //father
    int status=0;

    printf("父进程开始运行\n");
    pid_t ret = waitpid(-1, &status, 0); //阻塞式等待
    if(ret>0)
    {
      printf("wait succes, exit code: %d\n", WEXITSTATUS(status));
    }

  }
  
  return 0;
}

mycmd.c文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char* argv[])
{
  if(argc != 2){printf("can not execute! \n"); exit(1); }

  printf("获取环境变量: MY_PATH_VAL: %s\n", getenv("MY_PATH_VAL"));

  if(strcmp(argv[1], "-a")==0)
  {
    printf("hello a! \n");
  }
  else if(strcmp(argv[1], "-b")==0)
  {
    printf("hello b! \n");
  }
  else
  {
    printf("default! \n");
  }

  return 0;
}

结果展示:
在这里插入图片描述
事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。
它们之间的关系:
在这里插入图片描述

相关文章:

  • 时间复杂度与空间复杂度
  • 【Leetcode】背包问题-416. 分割等和子集
  • 【算法作业】实验五-2:一元三次方程的根-连续区间的二分搜索求近似解
  • 京东面试——算法工程师
  • 【C#】【平时作业】习题-12-事件
  • 文件IO(刷BMP格式图片、JPG格式图片)
  • 矩阵顺时针反转
  • arm-2d移植到OneOS上的使用
  • 文章说明86145B安捷伦光学分析仪86145B
  • 网课答案查题功能调用接口
  • 『Halcon与C#混合编程』012_迈德威视工业相机SDK入门
  • 以太坊合并可能会引发的雪崩
  • 记一次Prometheus监控下的“内存飙升”事件
  • Linux——进程操作之创建
  • 葡聚糖-聚乙烯亚胺Dextran-PEI,聚乙烯亚胺修饰纤维二糖/香菇多糖/辣根过氧化氢酶/溶菌酶
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • css属性的继承、初识值、计算值、当前值、应用值
  • Gradle 5.0 正式版发布
  • java中的hashCode
  • Linux中的硬链接与软链接
  • node入门
  • Spring Boot MyBatis配置多种数据库
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • vue-loader 源码解析系列之 selector
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 1.Ext JS 建立web开发工程
  • Linux权限管理(week1_day5)--技术流ken
  • ​ArcGIS Pro 如何批量删除字段
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • $jQuery 重写Alert样式方法
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (bean配置类的注解开发)学习Spring的第十三天
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (译) 函数式 JS #1:简介
  • (正则)提取页面里的img标签
  • (转)http-server应用
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .Net(C#)自定义WinForm控件之小结篇
  • .sdf和.msp文件读取
  • :中兴通讯为何成功
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [2010-8-30]
  • [CSS] 点击事件触发的动画
  • [C语言]——函数递归
  • [DM复习]关联规则挖掘(下)
  • [EWS]查找 文件夹
  • [GN] 后端接口已经写好 初次布局前端需要的操作(例)
  • [javaSE] GUI(Action事件)
  • [leetcode] 四数之和 M
  • [Lua实战]整理Lua中忽略的问题
  • [MFC] MFC消息机制的补充
  • [NOIP2003 普及组] 乒乓球(模拟)
  • [Paper]Application of deep convolutional neural network for automated detection of myocardial...