Linux:进程终止和进程替换

关于使用CMT2300A FIFO缓存区间设置为64Byte的问题 帮助你解决在使用CMT2300A 时遇到的各种问题,若有需要,请及时与我交流 阅读详情

一、进程终止

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;
}
【2024/3/12 更新】Windows Server 2019 服务配置与管理汇总 本栏目一共介绍了17种Windows Server 2019 的服务配置与管理,为了方便大家阅读理解,特意总结了17种服务的一些内容。具体说明如下所示 阅读详情

相关推荐

新手如何结合pbootCMS和宝塔面板快速构建网站

摘要: 新手可通过pbootCMS(轻量CMS)和宝塔面板(可视化工具)快速搭建网站,无需命令行。步骤包括:1) 准备服务器(Linux/CentOS7.x)和域名;2) 安装宝塔面板并配置LNMP环境(PHP7.4+MySQL5.7);3) 创建网站目录,上传并解压pbootCMS源码,设置文件权限;4) 运行安装向导,填写数据库信息和管理员账号;5) 测试前台/后台功能,优化性能并绑定域名。全程约30-60分钟,宝塔简化运维,pbootCMS便于内容管理,适合零基础用户。注意定期更新和备份以保障安全。

qinzhenyan的博客 1638

Linux命令之退出exit

`exit` 命令用于退出 shell 或者脚本,并返回给定值。

二木成林 8686

嵌入式统一消息机制:模块解耦与零拷贝通信设计

在嵌入式系统开发中,模块间通信(IMC)是影响可维护性与实时性的关键环节。传统IPC方式如全局变量、信号量或Socket易导致高耦合、调试困难及跨平台适配成本高。统一消息机制通过逻辑地址抽象、标签/实体分离、路由表驱动等原理,实现控制流与数据流解耦,在裸机、RTOS及Linux用户态保持一致接口。其技术价值在于降低模块依赖复杂度、支持动态增删与分布式迁移,并通过零拷贝优化显著减少CPU与内存开销。典型应用场景涵盖工业网关、城域交换机、多核ARM边缘设备等资源受限环境,尤其适用于需长期稳定运行、快速迭代与混合

weixin_35257663的博客 250

linux进程控制——进程创建、运行、exit终止——详解解析!

linux进程控制——异常、exit

strive_mianyang的博客 2093

Proteus 8.15仿真STM32F103C8,ADC采样总为0?别急着换芯片,先检查这3个配置

本文详细解析了在Proteus 8.15中仿真STM32F103C8时ADC采样值为0的常见原因及解决方法。从供电网络配置、时钟设置到ADC参数调整,提供了系统性的排查指南,帮助开发者快速定位问题,避免不必要的硬件更换。重点关注供电网络、时钟分频和ADC配置等关键环节。

weixin_30425949的博客 366

<视觉>——单目相机的标定(简单原理+Opencv实现)

单目相机的标定原理大致如下: 世界坐标到像素坐标的转换。 期间的参数有S尺度因子,内参矩阵K,旋转矩阵R,平移矩阵T,一共八个未知数。 在Opencv中我们可以方便的根据相机拍摄不同位姿的标定板图片来标定相机,从而求得这些参数,从而可以将相机下的坐标和实际的世界坐标联系起来,求取单应性矩阵H 参考: 单目相机综述:写的特别好 https://www.cnblo...

Kano365的博客 1万+

Linux exit命令教程:如何优雅地退出你的Shell(附案例详解和注意事项)

Linux的exit命令用于退出当前运行的shell。它可以接受一个参数[N],并以状态N退出shell。如果没有提供n,则它只返回最后执行的命令的状态。在计算机编程中,exit 是一个常用的命令,用于从程序、脚本或命令行中退出。它通常会终止当前运行的进程,并且可以向操作系统返回一个状态码,表示程序的退出状态。这个状态码可以用来表明程序是正常退出还是因为某种错误或异常而退出。

u012964600的博客 1万+

MyBatis-Plus 实战:敏感字段自动加解密支持模糊查询

本文基于MyBatis-Plus框架提出了一种全链路敏感字段加密方案。通过自定义TypeHandler实现数据入库自动加密和查询自动解密,结合重写LambdaQueryWrapper处理查询条件加密,并适配多种查询方式。方案核心包括:1)AESUtil工具类提供加解密基础能力;2)EncryptTypeHandler实现字段类型转换;3)实体类通过注解配置加密字段。该方案在保证数据安全的同时,对业务代码侵入性小,支持姓名、手机号等敏感信息的全流程加密处理,满足系统开发的安全需求。

蔡定努 595

Linux exit 命令详解:

exit命令用于退出当前的 shell 会话。它常用于脚本的结束部分或在命令行界面中退出交互式的 shell 会话。exit也可以指定一个退出状态码,用于指示程序的执行状态。exit命令是 Linux 系统中常用的命令,用于退出 shell 会话或脚本执行。通过指定退出状态码,exit可以帮助用户了解程序的执行结果或脚本的执行状态。使用得当可以提高脚本的可控性和可维护性。

yangchuang111213的博客 1527

PostgreSQL的学习心得和知识总结(八十二)|深入理解PostgreSQL数据库SQL语句的词法解析和语法解析流程

postgresql 词法解析语法解析流程

孤傲小二~阿沐的博客 5445

W5500以太网&PoE扩展模块原理图设计,已量产

本文将以 W5500 以太网 & PoE 扩展板为对象,从嵌入式硬件设计的视角,深度拆解其电路架构、核心器件选型、关键功能实现,以及这款板子解决行业痛点的设计思路。

不脱发的程序猿 933

Linux -- exit()函数、_exit()函数、return的说明与使用

exit()函数和_exit()函数都是用来 终止进程 的。 return是C语言关键字,主要用于子函数的返回,标识这个子函数的结束。

青椒*^_^*凤爪爪的博客 1万+

SAP 消息号T-CODE

SAP消息号修改汇总 确实有很多消息是可以修改的 FI: oBA5|oFMG|oFPM MM: oMRM|oKZZ|oMT4|oMCQ|o04C| SD: oVAH(V4)|oVM1(VL) CO:  oPR4_ACT|oPR4_CK|oPR4_CKML|oPR4_CKPF|oPR4_KKA|oPR4_KKP|oPR4_KKS| oPR4_KKS1|oPR4_P

heng0757的专栏 1万+

Linux 进程控制 :进程创建,进程终止,进程等待,程序替换

文章目录进程创建fork函数**vfork函数**进程终止进程等待程序替换 进程创建 fork函数 创建一个子进程,父子进程代码共享,数据独有。 当调用 fork函数 时,通过 写时拷贝技术 来拷贝父进程的信息。 写时拷贝技术: 子进程通过复制父进程的 PCB,使得父子进程指向同一块物理内存,运行位置和代码也相同。但又因为进程的独立性,所以当某一个进程数据发生改变的时候会重新给子进程开辟物理内存,将数据拷贝过去。(之所以这样使用是因为如果数据不修改的话还开辟空间拷贝数据会使效率降低)这也就是数据独有的原

Jormungand_V的博客 605

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Linux 进程控制:创建、终止、等待与程序替换全解析

本文聚焦于 Linux 进程控制的核心知识。创建、终止、等待与程序替换,讲解十分详细!

A Charmer 的博客 1786

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Linux进程控制:创建、终止与替换

本文摘要了Linux进程管理的核心概念:1)进程创建:通过fork()实现,采用写时拷贝技术提高效率;2)进程终止:介绍exit()、_exit()和return三种退出方式及区别;3)进程等待:使用wait()和waitpid()回收子进程资源,防止僵尸进程;4)进程替换:exec函数族实现程序替换而不创建新进程,详细说明各变体函数参数差异。文章通过代码示例和图示,系统性地阐述了进程生命周期管理的关键技术点。

2401_86525813的博客 460

【Linux】深入解析进程控制:创建、终止、等待与替换的原理与应用

进程控制是操作系统中的一个核心概念,涉及到进程的创建、终止、等待以及程序替换等方面。本文将介绍进程创建、终止、等待和程序替换的相关内容,包括fork函数的原理、写时拷贝机制、进程退出的场景和方法、进程等待的方法以及exec函数族的介绍。我们的程序只能执行我们的代码如果我们创建的子进程,想执行其他程序的代码呢?当一个进程调用exec函数时,该进程的用户空间代码和数据将被新程序替换,从新程序的启动例程开始执行。这意味着进程不再执行原来的代码,而是执行新程序的代码。

Colorful___的博客 1339

【Linux】进程控制:创建、终止、等待与替换全解析

本文将用最直白的语言带你掌握Linux进程管理的四大核心操作!包含大量代码示例与图解,建议边看边动手实践!本文篇幅较大,设计知识点众多,所以有几个点并没有深入讨论,如核心转储、exel接口函数中的环境变量表如何使用等,这些内容会在后续学习中逐渐补全。

weixin_51821336的博客 901

Linux - 进程控制:进程创建、进程终止、进程等待及进程程序替换

进程创建:fork初识、返回值写时拷贝、常规用法、调用失败原因;进程终止:进程退出场景、进程退出码、进程正常退出、return退出、exit、_exit、return、exit和_exit之间的区别与联系、进程异常退出;进程等待:必要性、获取子进程status、进程等待的方法、wait、waitpid、多进程创建以及等待的代码模型、基于非阻塞接口的轮询检测方案;进程程序替换:替换原理、替换函数、函数解释、命名理解。

Russ_Leo的博客 1304

【Linux】进程控制:创建、等待、终止和替换

什么是进程呢?在前面的博客中已经类比进程和线程做了详细介绍,这里简单提一下,不再赘述。 一、进程 1、进程基本概念 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统...

weixin_38682277的博客 275

Linux进程控制详解:fork创建、进程终止、wait等待与exec程序替换

本文详细介绍了Linux进程控制的核心机制,包括进程创建、终止、等待和程序替换四个关键环节。 1. 进程创建:通过fork()系统调用创建子进程,采用写时拷贝技术提高效率。父子进程共享代码但拥有独立数据空间,fork()在父进程返回子进程PID,在子进程返回0。 2. 进程终止:分为正常终止(return/exit/_exit)和异常终止(信号)。exit()会执行用户态清理,而_exit()直接进入内核终止流程。退出码低8位有效,0表示成功,非0表示失败。 3. 进程等待:使用wait()/waitpid

meilindehuzi_a的博客 564

Linux 进程控制(上):创建、终止、等待与程序替换

程序替换是指一个正在运行的进程,通过调用特定的系统调用(exec 系列函数),将一个全新的可执行程序加载到自己当前的进程地址空间中综上所述,进程控制本质上是对进程生命周期的管理。从创建进程开始,到进程的正常或异常终止,再到父进程对其进行等待与回收,最后通过程序替换实现功能切换,这一系列机制共同构成了操作系统对进程的基本控制能力。

cui_ruicheng的博客 423

Linux进程控制核心:创建·等待·终止·替换

/ 返回值:// >0: 父进程,返回值为子进程PID// =0: 子进程// <0: 创建失败为了让父进程方便对子进程进行标识,进而进行管理,所以给父进程子进程的pid,给子进程返回0只是为了确认是否创建成功,出错返回-1//等待最近一个子进程退出//等待pid为pid进程的退出,若pid参数值为-1,则等待任意一个子进程,与wait等效//这两个函数返回值正常返回时为收集到的子进程id,如果调用出错则返回-1调用这两个其中某一个函数时,父进程会进入阻塞等待状态,等待子进程状态发生改变。

2301_79969685的博客 855

Linux 进程控制:全面深入剖析进程创建、终止、替换与等待

exec()函数族用于用新的程序替换当前进程的映像,替换后,进程的 PID 保持不变,但执行的程序变成了新的程序。常用的exec()execl():通过参数列表传递新程序的参数。execv():通过参数数组传递新程序的参数。execvp():自动搜索PATH环境变量指定的路径,查找新程序。通过深入理解 Linux 的进程控制原语,包括fork()exec()exit()和wait()

conkl的博客 753

Linux复习:进程二 《进程创建》《进程终止》《进程替换》《进程程序替换》

一,进程创建 1.fork函数初始: fork之后,父子进程代码共享,数据以写实拷贝的形式各自私有一份 2.fork的常规用法 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。 3.fork调用失败的原因 系统中有太多的进程 实际用户的进程数超过了限制 ...

dpfxaca6的博客 303

【Linux系统#3】进程详解:进程的创建&终止&等待&替换

✨当时只道是寻常🌏📃1. 前言🌈之前在这两篇文章中我们已经了解过了进程的基本概念,这一章我们要进一步的学习进程,即 ****。2. 进程创建🖊2.1 fork()函数的深入了解之前博客里面我们讲过了,现在只是来做个温习2.1.1 利用fork()创建进程fork()返回相应的返回值,因此我们就可以知道fork()创建一个进程之所以会有两个返回值的原因在函数内部的执行的过程中,就已经创建了一个新的进程,所以新的进程会有一个返回值,而父进程也会有一个返回值2.2 fork 函数返回值。

island1314的博客 1525

【Linux】进程控制:理解什么是进程创建,进程终止,进程等待 | 进程替换

进程控制:理解什么是进程创建 | 进程终止 | 进程等待 | 进程替换 | 创建一个自己的shell

旋律 | 话语 | 色彩 | 情景 485
上一篇: Linux: 命令行参数和环境变量究竟是什么?
下一篇: Linux文件:EXT2文件系统工作原理 & 软硬链接
小白debug~
小白debug~ 新星创作者: C/C++技术领域 新星创作者: C/C++技术领域
博客等级 码龄4年 3510粉丝 128原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白debug~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值