Linux多进程编程之exec函数族使用

news2024/11/15 13:52:40

Linux多进程编程之exec函数族使用

  • 1.exec函数族是什么
  • 2.execl函数具体使用
  • 3.execlp
  • 4.exec后面不同字母所代表的含义

1.exec函数族是什么

顾名思义,它并不只是一个函数,而是以exec开头的六个函数,并且是没有exec这个函数的(就像TCP/IP协议族不只是TCP和IP两个协议一样):

       int execl(const char *path, const char *arg, ...
                       /* (char  *) NULL */);
       int execlp(const char *file, const char *arg, ...
                       /* (char  *) NULL */);
       int execle(const char *path, const char *arg, ...
                       /*, (char *) NULL, 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[]);

它们的作用就是在使用fork产生多进程之后,可以将子进程的进程空间替换成我们想要执行的程序,产生一个金蝉脱壳的效果。因为很多时候我们并不想让子进程一样的执行父进程的代码,因为子进程复制了父进程的进程空间,一样的代码和变量。而使用exec函数族则可以让子进程换成其它的可执行程序。
而在exec函数族当中,如上面的代码所示,最常用的起始就是前两个函数,execl和execlp。所以下面具体讲解前两个函数的具体用法,其它函数当然也会介绍如何使用。

2.execl函数具体使用

首先我们可以先生成一个可执行程序:

//hello.c
#include <stdio.h>

int main() {
    printf("hello Ntt!\n");
    return 0;
}

然后可以在Linux下编译一下:

sudo gcc hello.c -o hello

关于execl的解读:

int execl(const char *path, const char *arg, ...
                       /* (char  *) NULL */);

第一个参数path代表的是可执行文件的路径,可以使用绝对路径或者相对路径,推荐使用绝对路径。后面的都是这个可执行文件的参数,以NULL作为结尾,这里注意,虽然我们hello程序没有其它的参数,但它本身就算参数的一部分,所以下面可见具体使用:

//excel.c
//CSDN Credic1017
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    pid_t pid = fork();
    if(pid > 0) {
        printf("I am parent process. and pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(1);
    }else if(pid == 0) {
        execl("hello", "hello", NULL);
        //下面的代码不会执行
        printf("I am child process. and pid=%d, ppid=%d\n", getpid(), getppid());
    }
    return 0;
}

编译一下:

sudo gcc excel.c -o excel

并且在return 0前面再放个打印语句,子进程也不会执行该打印语句,因为它的进程空间全部被替换了,替换成了我们的hello可执行程序。
这里的话还可以调用Linux本身的程序,比如查看系统进程状态 ps aux,那么这里同理,ps所在的位置可用which查看,ps作为第一个参数,aux作为第二个参数,都是以字符数组存在的参数,最后以NULL结尾。

//excel.c
//CSDN Credic1017
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    pid_t pid = fork();
    if(pid > 0) {
        printf("I am parent process. and pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(1);
    }else if(pid == 0) {
        execl("/bin/ps", "ps", "aux", NULL);
        //下面的代码不会执行
        printf("I am child process. and pid=%d, ppid=%d\n", getpid(), getppid());
    }
    return 0;
}

3.execlp

int execlp(const char *file, const char *arg, ...
                       /* (char  *) NULL */);

这里只讲和execl的区别,第一个参数由path改为了file,file直接就为需要执行的可执行文件的文件名,就比如hello,像之前的path,就是要选定文件的相对路径或者绝对路径。当然ps也是直接写的,而不是像之前的/bin/ps。后面的参数还是一样的。

execlp("ps", "ps", "aux", NULL);

它也会和之前的运行结果一样,主要是他会到环境变量中去找。如果环境变量没找到则返回失败的参数。

4.exec后面不同字母所代表的含义

在这里插入图片描述
前面在execl中已经使用了l,其实就是代表参数地址以空指针结尾,使用了参数地址列表。
p的话也介绍了,其实就是在可执行程序那块会自动调用环境变量,从而可以少写点路径名。
那再看到exec后面带v的一个用法:

//声明:
int execv(const char *path, char *const argv[]);

//使用:
char *argv = {"ps", "aux", NULL};
execv("/bin/ps", argv);

那再看到exec后面带e的一个用法:
对于e结尾的解读就是存有环境变量字符串地址的指针数组的地址。

#include <unistd.h>
int execve(const char *filename, char *const argv[],
                  char *const envp[]);

//使用:
char *const envp[] = {"/home/NTT", "/home/aaa", "/home/bbb"};
char *argv = {"ps", "aux", NULL};
execve("/bin/ps", argv, envp);

所以,结合exec后面每种字母代表的含义能正确的使用exec函数族,遇事不决找男人(man)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/130926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

几行代码演示linux kernel、libc、userSpace app的关系

问一&#xff1a;编译出来的Linux内核镜像(".\build\arch\arm64\boot\Image")&#xff0c;可以单独运行吗&#xff1f;答案是能&#xff0c;但是加载完就提示panic&#xff0c;然后死掉了。 原因是&#xff1a; 内核代码加载完后&#xff0c;一定要切换到低权限模式…

Wireshark TS | Packet Challenge 之 HTTP 案例分析

前言 来自于 Sharkfest Packet Challenge 中的一个数据包案例&#xff0c;Sharkfest 是 Wireshark 官方组织的一年一度的大会&#xff0c;致力于在 Wireshark 开发人员和用户社区之间分享知识、经验和最佳实践。印象中早期是一年一次&#xff0c;近几年发展成一年两次&#xf…

我的2022年终总结

目录 1 序 1 2 工作 1 3 业余 1 3.1 AI 1 3.2 数学小插曲 3 3.3 金融投资 3 4 生活 4 5 最后 4 1 序 老婆大人每年这个时候都要写年终总结&#xff0c;现在也正在写&#xff1b;CSDN也发起了年终征文活动&#xff1b;各大app也各种年度大数据总结。我好像还是第一次写年终总…

两两交换链表中的节点 -- 虚拟头节点

24两两交换链表中的节点 – 虚拟头节点 通过本题可以&#xff1a; 增加对虚拟头节点的理解。 加强对链表这一基本数据结构的基本操作的理解。 1. 交换过程&#xff1a; 如图&#xff0c;假设链表如图所示。 为了减少对头节点的单独讨论&#xff0c;这里采用虚拟头节点进行…

Allegro如何显示走线和铜皮的网络名操作指导

Allegro如何显示走线和铜皮的网络名操作指导 在做PCB设计的时候,如果可以实时看到走线和铜皮的网络名,对于设计有很大帮助,如下图 具体操作如下 选择Set-up-user preferences选择Display

Vue 总结一(简介 基本语法)

目录 Vue 是什么 与其它 JS 框架的关联 Vue 周边库 MVVM模型 怎么用 Vue模板语法有2大类&#xff1a; 数据绑定 data 事件 v-on methods 计算属性 computed 监视属性 watch computed和watch之间的区别&#xff1a; 条件渲染 v-if v-show Vue 是什么 一个动态构建用…

sql根据团队树一级一级汇总统计

1、需求描述 最近碰到了一个需求&#xff0c;是要统计各个团队的员工的销售金额&#xff0c;然后一级一级向上汇总。 架构团队树是类似于这种样子的&#xff0c;需要先算出每个员工的销售金额&#xff0c;然后汇总成上一级的团队金额&#xff0c;然后各个团队的销售总金额再往上…

京东技术发展简史

文章目录前言京东发展历程京东商城技术的演进京东自研技术分布式数据库StarDB京东云移动端Flutter在京东的实践大数据咚咚架构ShardingSphere京东人物参考“京东可以高速发展到今天的规模的原因&#xff0c;其中最核心的是坚持“倒三角”战略&#xff1a;建立出色的团队&#x…

转义字符与strlen(),sizeof()在一起的注意事项

转义字符与strlen(),sizeof() 1. 转义字符每个人都知道是怎么一回事儿&#xff0c;转义字符顾名思义就是转变意思。 2. 首先转义字符肯定是一个字符&#xff0c;不是两个字符&#xff0c;更不用说是数字了&#xff0c;就是字符。 3. 当用strlen()统计字符串长度时或者用sizeo…

2022年度回顾

这一年是不平凡的一年&#xff0c;换了公司&#xff0c;新公司频繁出差&#xff0c;去了临沂&#xff0c;去了河南&#xff0c;去了唐山&#xff0c;去了福鼎&#xff0c;当中最印象深刻的还是河南&#xff0c;项目万分火急&#xff0c;在疫情隔绝的10月份毅然决然的前往河南安…

如何稍微优雅滴完成博文访问计数[SpringBoot+redis+分布式锁]

文章目录前言背景朴素做法Redis方案流量统计接口演示自定义注解计数实现防刷加锁完整代码数据一致性分析自定义注解返回值分析解决方案总结前言 okey,我们来收尾一下&#xff0c;这公历纪年2022年12月31日。这是本年度的最后一篇博文。那么这篇博文主要是用来实现博文的一个访…

【LeetCode】被围绕的区域 [M](深度优先遍历)

130. 被围绕的区域 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域里所有的 O 用 X 填充。 示例 1&#xff1a; 输入&#xff1a;board [[&quo…

浅谈Flink批模式Adaptive Hash Join

Flink批Hash Join递归超限问题 随着Flink流批一体能力的迅速发展以及Flink SQL易用性的提升&#xff0c;越来越多的厂商开始将Flink作为离线批处理引擎使用。在我们使用Flink进行大规模join操作时&#xff0c;也许会发生如下的异常&#xff0c;导致任务失败&#xff1a; Hash j…

Es进阶检索

本文用到的测试数据及所有代码链接&#xff1a; https://blog.csdn.net/m0_62436868/article/details/128505566?spm1001.2014.3001.5501 1、SearchAPI ES 支持两种基本方式检索 : 一个是通过使用 REST request URI 发送搜索参数&#xff08;uri检索参数&#xff09; 另…

基于华为eNSP的中小企业办公园区网络规划与设计

目录一、需求分析&#xff08;一&#xff09;项目背景&#xff08;二&#xff09;网络业务需求&#xff08;三&#xff09;网络应用需求二、网络结构设计三、网络拓扑图四、网络设备基本配置五、项目测试结语运用到的技术有&#xff1a; 1、虚拟局域网&#xff08;VLAN&#xf…

人工智能--你需要知道的一切

人工智能--你需要知道的一切 人工智能是当今最受关注的技术之一。但它究竟是什么&#xff1f;你为什么要关心&#xff1f; 人工智能是当今最受关注的技术之一。但它到底是什么&#xff1f;你为什么要关心&#xff1f;在这里&#xff0c;我们将介绍你需要知道的关于人工智能的…

java开发的美妆化妆品电商商城系统

简介 Java基于ssm(可以转springboot项目哦)开发的美妆商城系统&#xff0c;主要是卖化妆品的系统&#xff0c;用户可以浏览商品&#xff0c;加入购物车&#xff0c;下单&#xff0c;在个人中心管理自己的订单。管理员可以管理自己的商品&#xff0c;发布商品&#xff0c;上下架…

2023年留学基金委(CSC)公派访问学者博士后项目选派办法及解读

2023年即将伊始。知识人网祝大家新年快乐&#xff0c;心想事成&#xff01;同时提醒申请者关注国家留学基金委&#xff08;CSC&#xff09;的申报政策。目前CSC官网已经发布了2023年公派访问学者、博士后的项目通知&#xff0c;知识人网小编现将其选派工作流程及选派办法原文转…

C语言 自定义类型

结构体内存对齐 解释1 从内存开始位置存放 解释二 int对齐数是4 vs默认对齐数是8 取其较小值的倍数 那就是4的位置存放 char 对数1 vs是8默认 谁的较小值对数是1 那就是任意数 所以c2防砸8 如下图绿色部分 struct S2 {char c1;int i;double d;//8 };输出结果16 struct S4 …

当我们身边没有示波器就无法测量频率与占空比了?一招教你解决身边没有示波器时如何测量STM32定时器产生PWM的频率与占空比

当我们身边没有示波器就无法测量频率与占空比了&#xff1f;这篇文件小编就教大家如何使用定时器输入捕获功能测量频率与占空比。 原理解析 定时器输入捕获一般应用在两个方面&#xff0c;一个方面是脉冲跳变沿时间测量&#xff0c;另一方面是 PWM输入测量。下面将要使用就是测…