进程替换讲解

1. 基本概念

1.1 进程替换 vs. 进程创建

  • 进程创建:使用fork()clone()等系统调用创建一个新的子进程,子进程是父进程的副本,拥有相同的代码和数据。
  • 进程替换:使用exec系列函数在当前进程中加载并执行一个新的程序,替换掉当前进程的映像,但保留PID、文件描述符等资源。

1.2 exec系列函数

exec系列函数用于在当前进程中执行一个新程序。常见的exec函数包括:

这些函数的命名规则如下:

  • 前缀exec
  • 中间部分
    • l(list):参数以列表形式传递。
    • v(vector):参数以数组形式传递。
  • 后缀
    • e:允许传递环境变量。
    • p:使用PATH环境变量来查找可执行文件。

2. 常用的exec函数

2.1 execl()

函数原型:

 

#include <unistd.h>int execl(const char *path, const char *arg, ... /* (char  *) NULL */);

参数:

  • path:要执行的可执行文件的路径。
  • arg:第一个参数,通常是程序名。
  • ...:可变参数列表,以NULL结尾。

 例子:

#include <stdio.h>
#include <unistd.h>int main() {printf("Before execl\n");execl("/bin/ls", "ls", "-l", NULL);// 如果execl成功,以下代码不会执行perror("execl failed");return 1;
}

2.2 execv()

函数原型:

#include <unistd.h>int execv(const char *path, char *const argv[]);

参数:

  • path:要执行的可执行文件的路径。
  • argv:参数数组,以NULL结尾。

例子:

#include <stdio.h>
#include <unistd.h>int main() {char *args[] = { "ls", "-l", NULL };printf("Before execv\n");execv("/bin/ls", args);// 如果execv成功,以下代码不会执行perror("execv failed");return 1;
}

2.3 execlp()

函数原型:

#include <unistd.h>int execlp(const char *file, const char *arg, ... /* (char  *) NULL */);

参数:

  • file:可执行文件名,会在PATH环境变量中查找。
  • arg:第一个参数,通常是程序名。
  • ...:可变参数列表,以NULL结尾。

例子:

#include <stdio.h>
#include <unistd.h>int main() {printf("Before execlp\n");execlp("ls", "ls", "-l", NULL);// 如果execlp成功,以下代码不会执行perror("execlp failed");return 1;
}

2.4 execvp()

函数原型:

#include <unistd.h>int execvp(const char *file, char *const argv[]);

参数:

  • file:可执行文件名,会在PATH环境变量中查找。
  • argv:参数数组,以NULL结尾。

例子:

#include <stdio.h>
#include <unistd.h>int main() {char *args[] = { "ls", "-l", NULL };printf("Before execvp\n");execvp("ls", args);// 如果execvp成功,以下代码不会执行perror("execvp failed");return 1;
}

2.5 execle()

函数原型:

#include <unistd.h>int execle(const char *path, const char *arg, ... /* (char  *) NULL, char * const envp[] */);

参数:

  • path:要执行的可执行文件的路径。
  • arg:第一个参数,通常是程序名。
  • ...:可变参数列表,以NULL结尾。
  • envp:环境变量数组。

例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {char *env[] = { "PATH=/bin", NULL };printf("Before execle\n");execle("/bin/ls", "ls", "-l", NULL, env);// 如果execle成功,以下代码不会执行perror("execle failed");return 1;
}

2.6 execvpe()

#include <unistd.h>int execvpe(const char *file, char *const argv[], char *const envp[]);
 参数
  • file:要执行的可执行文件的名称。如果 file 中包含斜杠 (/),则将其视为路径名,直接尝试执行。(如果 file 不包含斜杠,则会在 PATH 环境变量指定的目录中查找可执行文件。)

  • argv:参数数组,以 NULL 结尾。argv[0] 通常是程序名。

  • envp:环境变量数组,以 NULL 结尾。每个环境变量以 "NAME=VALUE" 的形式表示。

例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 要执行的程序及其参数char *args[] = { "printenv", "MY_VAR", NULL };// 自定义环境变量char *env[] = { "MY_VAR=HelloWorld", "PATH=/bin:/usr/bin", NULL };printf("Before execvpe\n");// 执行程序if(execvpe("printenv", args, env) == -1) {perror("execvpe failed");exit(1);}// 如果 execvpe 成功,以下代码不会执行return 0;
}

 

 

 

2.7 execve()(这个上面查库没有,要单独查)

函数原型:

 

 

参数:

  • pathname:要执行的可执行文件的路径。
  • argv:参数数组,以NULL结尾。
  • envp:环境变量数组。

例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {char *args[] = { "ls", "-l", NULL };char *env[] = { "PATH=/bin", NULL };printf("Before execve\n");execve("/bin/ls", args, env);// 如果execve成功,以下代码不会执行perror("execve failed");return 1;
}

 

3. 错误处理

大多数exec函数在成功时不会返回,如果失败则返回-1,并设置errno变量。常见的错误包括:

  • ENOENT:文件不存在。
  • EACCES:权限不足。
  • ENOEXEC:可执行文件格式错误。

例子:

#include <stdio.h>
#include <unistd.h>int main() {if(execl("/bin/ls", "ls", "-l", NULL) == -1) {perror("execl failed");}// 如果execl成功,以下代码不会执行return 1;
}

 

 

 

 

 

 

 

 

 

 

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

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

相关文章

【微服务】SpringBoot + Docker 实现微服务容器多节点负载均衡详解

目录 一、前言 二、前置准备 2.1 基本环境 2.2 准备一个springboot工程 2.2.1 准备几个测试接口 2.3 准备Dockerfile文件 2.4 打包上传到服务器 三、制作微服务镜像与运行服务镜像 3.1 拷贝Dockerfile文件到服务器 3.2 制作服务镜像 3.3 启动镜像服务 3.4 访问一下服…

1.2.2.1.4 数据安全发展技术发展历程:高级公钥加密方案——同态加密

引言 在密码学领域&#xff0c;有一种技术被图灵奖得主、著名密码学家Oded Goldreich誉为"密码学圣杯"&#xff0c;那就是全同态加密&#xff08;Fully Homomorphic Encryption&#xff09;。今天我们就来聊聊这个神秘而强大的加密方案是如何从1978年的概念提出&…

vllm量化03—INT4 W4A16

本系列基于Qwen2.5-7B&#xff0c;学习如何使用vllm量化&#xff0c;并使用benchmark_serving.py、lm_eval 测试模型性能和评估模型准确度。 测试环境为&#xff1a; OS: centos 7 GPU: nvidia l40 driver: 550.54.15 CUDA: 12.3本文是该系列第3篇——INT4 W4A16 一、量化 f…

第二十五天打卡

常见报错类型 try-except-else-finally 语句 首先执行try语句&#xff0c;若正确直接执行else语句 若try语句发生错误&#xff0c;则判断错误类型&#xff0c;执行错误类型对应的except语句&#xff0c;不执行else语句 finally语句无条件执行&#xff0c;多用于资源保存&…

城市扫街人文街头纪实胶片电影感Lr调色预设,DNG/手机适配滤镜!

调色详情 城市扫街人文街头纪实胶片电影感 Lr 调色是通过 Lightroom&#xff08;Lr&#xff09;软件&#xff0c;对城市街头抓拍的人文纪实照片进行后期调色处理。旨在赋予照片如同胶片拍摄的质感以及电影般浓厚的叙事氛围&#xff0c;不放过每一个日常又珍贵的瞬间&#xff0c…

【hadoop】Kafka 安装部署

一、Kafka安装与配置 步骤&#xff1a; 1、使用XFTP将Kafka安装包kafka_2.12-2.8.1.tgz发送到master机器的主目录。 2、解压安装包&#xff1a; tar -zxvf ~/kafka_2.12-2.8.1.tgz 3、修改文件夹的名字&#xff0c;将其改为kafka&#xff0c;或者创建软连接也可&#xff1…

UDP 多点通信

一、setsockopt/getsockopt 函数详解 1. 函数原型 c #include <sys/socket.h> int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);…

说一说Node.js高性能开发中的I/O操作

众所周知&#xff0c;在软件开发的领域中&#xff0c;输入输出&#xff08;I/O&#xff09;操作是程序与外部世界交互的重要环节&#xff0c;比如从文件读取数据、向网络发送请求等。这段时间&#xff0c;也指导项目中一些项目的开发工作&#xff0c;发现在Node.js运用中&#…

Charles抓包并破解ProtoBuf请求

安装Charles并抓包 如果是外网的需要root安装一系列证书等&#xff0c;详细见参考文章&#xff1a; 在雷电模拟器安卓7.0上使用Charles抓包详细教程 遇到如下问题&#xff1a; 1.粘贴到目录/system/etc/security/cacerts内&#xff0c;粘贴不了。需要打开这个 2.模拟器wifi打…

Odoo 18 安全组与访问权限管理指南

Odoo 18 安全组与访问权限管理指南 一、准备工作&#xff1a;在自定义模块中创建安全配置文件 创建 security 文件夹 在自定义模块内创建名为 security 的文件夹&#xff0c;用于存放安全组和访问权限的定义文件。 二、定义模型访问权限&#xff1a;ir.model.access.csv 文…

使用lldb查看Rust不同类型的结构

目录 前言 正文 标量类型 复合类型——元组 复合类型——数组 函数 &str struct 可变数组vec Iter String Box Rc Arc RefCell Mutex RwLock Channel 总结 前言 笔者发现这个lldb挺好玩的&#xff0c;可以查看不同类型的结构&#xff0c;虽然这好像是C的东…

uniapp使用ui.request 请求流式输出

正文&#xff1a; 在现代Web开发中&#xff0c;实时数据流和长时间运行的请求变得越来越常见&#xff0c;尤其是在处理大量数据或进行实时通信时。在这种情况下&#xff0c;uniapp 提供的 ui.request 请求方法可以帮助我们轻松实现流式输出请求。本文将介绍如何使用 uni.reques…

如何恢复被勒索软件加密的服务器文件(解密与备份策略)

针对勒索软件加密文件的恢复和解密策略&#xff0c;结合当前数据安全最佳实践&#xff0c;整理应对指南如下&#xff1a; 一、文件解密与修复方法 立即隔离设备‌ 断开网络连接并禁用共享功能&#xff0c;防止病毒横向传播 通过文件后缀异常&#xff08;如.locked、.wxx&…

JS,ES,TS三者什么区别

Java Script(JS)、ECMAScript(ES)、TypeScript(TS) 的核心区别与关联的详细解析,结合技术背景、设计目标及应用场景展开说明: 一、核心定义与关系 JavaScript(JS) 定义:一种动态类型、基于原型的脚本语言,由 Netscape 公司于 1995 年首次开发,用于网页交互功能。角…

【MapReduce入门】深度解析MapReduce:定义、核心特点、优缺点及适用场景

目录 1 什么是MapReduce&#xff1f; 2 MapReduce的核心特点 2.1 分布式处理 2.2 容错机制 3 MapReduce的完整工作流程 4 MapReduce的优缺点分析 4.1 优势 4.2 局限性 5 MapReduce典型应用场景 5.1 适用场景 5.2 不适用场景 6 MapReduce与其他技术的对比 7 总结 1…

【Redis】分布式锁的实现

目录 一、本地锁存在的问题 二、redis实现分布式锁原理 三、使用示例 四、锁误删问题 解决思路 获取锁和释放锁代码优化 五、锁释放的原子性问题 解决思路&#xff08;Lua脚本&#xff09; 使用流程 总结 大家好&#xff0c;我是千语。上期给大家讲了使用悲观锁来解决…

Unity3D对象池设计与实现详解

前言 在Unity3D中&#xff0c;对象池&#xff08;Object Pooling&#xff09;是一种优化技术&#xff0c;用于减少频繁实例化和销毁对象带来的性能开销。以下是对象池的详细设计和实现步骤&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点…

[Spring]-组件的生命周期

组件生命周期 认识组件的声明周期 实验1 通过Bean指定组件的生命周期 package com.guigu.spring.ioc.bean;Data public class User {private String username;private String password;private Car car;Autowiredpublic void setCar(Car car) {System.out.println("自动…

【golang】网络数据包捕获库 gopacket

详解 github.com/google/gopacket/pcap 包 github.com/google/gopacket/pcap 是 Go 语言中一个强大的网络数据包捕获库&#xff0c;它是 gopacket 项目的一部分&#xff0c;提供了对 libpcap&#xff08;Linux/Unix&#xff09;和 WinPcap&#xff08;Windows&#xff09;的 G…

RBTree的模拟实现

1&#xff1a;红黑树的概念 红⿊树是⼀棵⼆叉搜索树&#xff0c;他的每个结点增加⼀个存储位来表⽰结点的颜⾊&#xff0c;可以是红⾊或者⿊⾊。通过对任何⼀条从根到叶⼦的路径上各个结点的颜⾊进⾏约束&#xff0c;红⿊树确保没有⼀条路径会⽐其他路径⻓出2倍&#xff0c;因…