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

Linux:进程终止和进程替换

Linux:Linux:进程终止和进程替换

  • 一、进程终止
    • 1.1 进程退出场景和创建退出方式
  • 1.2 exit 和 _exit区别
  • 二、进程程序替换
    • 2.1 进程替换函数
    • 2.2 函数解释及命名解释
      • 函数解释
      • 命名解释
    • 2.3 单进程程序替换(无子进程)
      • 2.3.1 带`l`函数进程替换(execl为例)
      • 2.3.2 带`p‘函数进程替换(execlp为例)
      • 2.3.3 execv、execvp替换函数应用实例
    • 2.4 进程替换其他程序,调用运行其他语言程序
  • 三、进程替换时环境变量的继承
    • 3.1 进程替换时,子进程环境变量由来
      • 3.2 为何父子进程间环境变量的继承不受进程替换的影响
      • 3.3 子进程获取环境变量的3种方式

一、进程终止

1.1 进程退出场景和创建退出方式

 进程退出有3种场景:代码执行完毕,结果正确;代码执行完毕,结果错误;代码异常终止!

 而进程退出的常见方式主要分为以下两大类:

正常终止
从main返回
调用exit退出
调用_exit退出
异常终止ctrl c, 信号终止

1.2 exit 和 _exit区别

  exit 和 _exit都可以直接终止进程。但_exit是系统调用接口,而exit为函数调用,底层封装了exit。
不同的是,exit终止进程时,会刷新缓冲区,执行用户的清理函数,关闭流等操作;而_exit则是直接“粗暴”的退出进程,不做任何其他工作!!

在这里插入图片描述

二、进程程序替换

 fork()创建子进程时,子进程执行的代码和数据都是父进程的一部分。如果我们想让子进程执行全新的代码,访问全新的数据,我们可以采用一种技术 —— 程序替换!而进程替换可以将命令行参数和环境变量传递给被替换程序的main()函数参数!!

2.1 进程替换函数

 进程替换函数有6种以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 execvpe(const char *file, char *const argv[], char *const envp[]);

 而exec函数底层都封装了系统调用接口execve的疯转,以实现不同的需求!

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

2.2 函数解释及命名解释

函数解释

  1. 如果这些函数调用成功,也就意味着进程替换成功。此时重新加载新的程序,从启动代码开始执行,并且不再返回。即进程替换后,执行新程序,执行完后直接退出!!
  2. 如果进程替换函数执行失败,此时返回值设为-1。
  3. exec函数只有出错的返回值,没有成功的返回值。

命名解释

  • l(list):参数采用列表形式。
  • v(vector):参数采用数组。
  • p(path):带p表示执行程序时,OS会自带去环境变量PATH中查找路径。
  • e(env):表示自己维护环境变量。

2.3 单进程程序替换(无子进程)

2.3.1 带l函数进程替换(execl为例)

 下面我们在一段代码的开头和结尾分别输出打印相关信息,然后两段信息输出代码直接调用execl替换ls -a-l

【源代码】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("pid: %d, ecec command begin!\n", getpid());//进程替换,执行ls指令相关程序execl("/usr/bin/ls", "ls", "-a", "-l", NULL);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

【运行结果】:

在这里插入图片描述

【函数参数原型解释】:


在这里插入图片描述



在这里插入图片描述


2.3.2 带`p‘函数进程替换(execlp为例)

【源代码】:(头文件省略)

int main()
{printf("pid: %d, ecec command begin!\n", getpid());execlp("pwd", "pwd", NULL);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

【运行结果】:

在这里插入图片描述

【函数参数原型解释】:
在这里插入图片描述
在这里插入图片描述

2.3.3 execv、execvp替换函数应用实例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main()
{char *const argv[] = {"ls","-l","-a",NULL};printf("pid: %d, ecec command begin!\n", getpid());// 和execl、execlv类似,只不过下面函数时通过指针数组的方式,指明替换程序的执行方式!!execv("/usr/bin/ls", argv);execvp("ls", argv);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

2.4 进程替换其他程序,调用运行其他语言程序

 上述所有的程序替换都是替换系统指令程序,那如何替换自己写的程序。
 下面我们在c程序中创建子进程,让子进程发送进程替换一段c++可执行程序,并且父进程等待子进程!!

【待替换C++程序】:

#include <iostream>int main()
{std::cout << "hello c++!" << std::endl;std::cout << "hello c++!" << std::endl;std::cout << "hello c++!" << std::endl;return 0;
}

【主代码C程序】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>extern char **environ;int main()
{pid_t id = fork();if(id == 0){printf("pid: %d, ecec command begin!\n", getpid());execl("./mytest", "mytest");//替换C++程序//替换失败,执行下面代码printf("pid: %d, ecec command end!\n", getpid());exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}

【运行结果】:

在这里插入图片描述

  • 为啥在c程序中,可以直接替换c++程序?根本原因在于exec函数发生的是进程替换,任何语言程序一旦运行起来就变成了进程,便可发生进程替换。系统大于一切!!

三、进程替换时环境变量的继承

3.1 进程替换时,子进程环境变量由来

 环境变量是数据,所有可以通过地址空间实现父子间通过写时拷贝的方式共享数据 —— 环境变量。所以当通过exec函数进行进程替换时,子进程的环境变量是直接从父进程来的。

3.2 为何父子进程间环境变量的继承不受进程替换的影响

 父进程和子进程间通过写时拷贝的方式,让环境变量别子进程继承,从而实现环境变量的全局性!但为何调用exec函数进行进程替换后,环境变量没有发生修改,变为被替换程序的环境变量?

 原因很简单,程序替换,只替换新程序的代码和数据,环境变量不会被替换!!

3.3 子进程获取环境变量的3种方式

  1. 操作系统直接将环境变量传递给子进程,子进程直接用。或者直接通过execle、execvpe的最后一个参数直接传递给子进程!

【实例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;int main()
{pid_t id = fork();if(id == 0){execle("./mytest", "mytest", NULL, environ);//进程替换,直接将environ传递给子进程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}
  1. 直接构造自己的环境变量表传递给子进程。

【实例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;int main()
{pid_t id = fork();if(id == 0){execle("./mytest", "mytest", NULL, environ);//进程替换,直接将environ传递给子进程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){char *const envp[] = {"MYENV1 = 111111111111111111","MYENV2 = 111111111111111111","MYENV3 = 111111111111111111",NULL};execle("./mytest", "mytest", NULL, envp);//直接将自己构造的函数变量表envp传递给子进程}return 0;
}
  1. 借助putenv(),新增环境变量给父进程然后传递给子进程

【实例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>extern char **environ;int main()
{pid_t id = fork();if(id == 0){char *myenv = "MYENV = 111111111111111111";putenv(myenv);//将环境变量MYENV添加到父进程环境变量表中execl("./mytest", "mytest");//直接传递给子进程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}

相关文章:

Linux:进程终止和进程替换

Linux&#xff1a;Linux&#xff1a;进程终止和进程替换 一、进程终止1.1 进程退出场景和创建退出方式 1.2 exit 和 _exit区别二、进程程序替换2.1 进程替换函数2.2 函数解释及命名解释函数解释命名解释 2.3 单进程程序替换&#xff08;无子进程&#xff09;2.3.1 带l函数进程替…...

使用Java实现异步消息处理与队列消费

使用Java实现异步消息处理与队列消费 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代软件系统中&#xff0c;处理异步消息和队列消费是常见的需求。通过…...

使用C++实现ATM系统,谈谈思路及代码实现

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…...

相机光学(二十四)——CRA角度

CRA角度 0.参考资料1.什么是CRA角度2.为什么 CRA 会导致luma shading3.为什么 CRA 会导致color shading4.CRA相差过大的具体表现5.CRA Matching6.怎样选择sensor的CRA 0.参考资料 1.芯片CRA角度与镜头的匹配关系&#xff08;一&#xff09;   2.芯片CRA角度与镜头选型的匹配关…...

python函数和c的区别有哪些

Python有很多内置函数&#xff08;build in function&#xff09;&#xff0c;不需要写头文件&#xff0c;Python还有很多强大的模块&#xff0c;需要时导入便可。C语言在这一点上远不及Python&#xff0c;大多时候都需要自己手动实现。 C语言中的函数&#xff0c;有着严格的顺…...

速看!这主食冻干评测极可能被商家恶意举报~PR、希喂和SC真实测评

我是一名专注于宠物健康的营养师&#xff0c;日常大部分时间都在与猫咪和狗狗为伴&#xff0c;对它们入店时的身体状况往往能迅速做出初步判断。当前&#xff0c;多数家养猫咪面临的肥胖和肝损伤问题尤为突出&#xff0c;尽管医疗干预能缓解病情&#xff0c;但要从根本上解决还…...

股票数据分析(K线图、均值图、MACD图、RSI图)--股票日数据

数据 数据是上证指数日行情数据&#xff0c;股票代码000002.sz&#xff0c;原始数据shdata示例如下&#xff1a; 读取数据&#xff1a; import numpy as np import pandas as pd import mplfinance as mpf import matplotlib.pyplot as plt from datetime import datetime imp…...

重写equals()方法为什么同时要重写hashcode()

equals()方法 equals()方法是Object类中的一个方法&#xff0c;在Object类中&#xff0c;equals等同于。 在不同的类中&#xff0c;往往会对equals()按需求进行重写。重写的目的都是&#xff1a;用于比较两个对象是否 "相等"。如果两个对象的内容相同&#xff0c;那…...

安全及应用(更新)

一、账号安全 1.1系统帐号清理 #查看/sbin/nologin结尾的文件并统计 [rootrootlocalhost ~]# grep /sbin/nologin$ /etc/passwd |wc -l 40#查看apache登录的shell [rootrootlocalhost ~]# grep apache /etc/passwd apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin#改变…...

Hadoop权威指南-读书笔记-03-Hadoop分布式文件系统

Hadoop权威指南-读书笔记 记录一下读这本书的时候觉得有意思或者重要的点~ 还是老样子~挑重点记录哈&#x1f601;有兴趣的小伙伴可以去看看原著&#x1f60a; 第三章 Hadoop分布式文件系统 当数据集的大小超过一台独立的物理计算机的存储能力时&#xff0c;就有必要对它进行分…...

Rust入门实战 编写Minecraft启动器#2建立资源模型

首发于Enaium的个人博客 我们需要声明几个结构体来存储游戏的资源信息&#xff0c;之后我们需要将json文件解析成这几个结构体&#xff0c;所以我们需要添加serde依赖。 serde { version "1.0", features ["derive"] }资源相关asset.rs use serde::De…...

小白学C++(第一天)基础入门

温馨提醒&#xff1a;本篇文章&#xff0c;请各位c基础不行的童鞋不要贸然观看 C的第一个程序 第一个关键字namespace namespace 是定义空间的名字的关键字&#xff0c;使用格式格式如下&#xff1a; namespace 空间名 { } 其中{ }内的命名空间的成员&#xff0c;可以定义…...

谷歌正在试行人脸识别办公室安全系统

内容提要&#xff1a; &#x1f9ff;据美国消费者新闻与商业频道 CNBC 获悉&#xff0c;谷歌正在为其企业园区安全测试面部追踪技术。 &#x1f9ff;测试最初在华盛顿州柯克兰的一间办公室进行。 &#x1f9ff;一份内部文件称&#xff0c;谷歌的安全和弹性服务 (GSRS) 团队将…...

【CSS01】CSS概述,使用样式的必要性,CSS语法及选择器

文章目录 一、什么是样式二、使用样式的必要性三、使用样式的几种方式四、CSS基本语法&#xff1a;五、CSS的注释六、CSS选择器——重点相关单词 一、什么是样式 概念&#xff1a; Cascade [kˈskeɪd] Style Sheet [ʃiːt] 级联样式单/表&#xff0c;层叠样式表 CSS有化腐…...

PostgreSQL的pg_bulkload工具

PostgreSQL的pg_bulkload工具 pg_bulkload 是一个针对 PostgreSQL 提供高性能批量数据加载的工具。相较于内置的 COPY 命令&#xff0c;pg_bulkload 更加灵活并且在许多情况下性能更高。它支持数据的强制加载、数据过滤、数据转换以及错误处理等多种功能&#xff0c;非常适合需…...

【Java伴学笔记】Day-01 命令行|环境|编译解释运行|Java的相关分支|Java的特性|字面量

一、关于命令行 图形化界面的缺点 需要加载图片等一系列资源 效率较低 命令行 CMDMicrosoft Learn-CMDWindows CMD常用命令大全&#xff08;值得收藏&#xff09; 二、环境 什么是JDK JDK是Java Development Kit的缩写&#xff0c;意为Java开发工具包。它是一个用于开发Java应用…...

如何使用Vue3创建在线三维模型展示?

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 代码相关的技术博客 代码应用场景介绍 本段代码使用 RoughJS 库在 HTML5 Canvas 上创建了手绘风格的图像&#xff0c;展示了 RoughJS 库的强大功能&#xff0c;可用于创建具有有机手绘外观的图形。 代码基本…...

使用ndoe实现自动化完成增删改查接口

使用ndoe实现自动化完成增删改查接口 最近工作内容比较繁琐&#xff0c;手里需要开发的项目需求比较多&#xff0c;常常在多个项目之间来回切换&#xff0c;有时候某些分支都不知道自己开发了什么、做了哪些需求&#xff0c; 使用手写笔记的方式去记录分支到头来也是眼花缭乱&a…...

排序 -- 手撕归并排序(递归和非递归写法)

一、基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有…...

防火墙基础及登录(华为)

目录 防火墙概述防火墙发展进程包过滤防火墙代理防火墙状态检测防火墙UTM下一代防火墙&#xff08;NGFW&#xff09; 防火墙分类按物理特性划分软件防火墙硬件防火墙 按性能划分百兆级别和千兆级别 按防火墙结构划分单一主机防火墙路由集成式防火墙分布式防火墙 华为防火墙利用…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...