【Linux系统】Linux进程终止的N种方式

Linux系列


文章目录

  • Linux系列
  • 前言
  • 一、进程终止的概念
  • 二、进程终止的场景
  • 三、进程终止的实现
    • 3.1 程序退出码
    • 3.2 运行完毕结果正常
    • 3.3 运行完毕结果异常
    • 3.4 程序异常退出
  • 总结


前言

进程终止是操作系统中,进程的一个重要阶段,他标志着进程生命周期的结束。在Linux下进程终止的方式有很多,接下来我会一一介绍。


一、进程终止的概念

进程终止是操作系统将正在运行的程序结束掉的过程。当进程终止时,操作系统会回收该进程所占用的系统资源,如内存空间、文件描述符、CPU资源等,确保系统资源高效的利用。

二、进程终止的场景

这里我们仅介绍常见的进程终止场景

场景原因
任务完成进程顺利执行完所有预设的任务,达到结束点,自动请求操作系统终止
运行错误进程执行过程中遇到除零错误、越界访问等
资源不足进程向操作系统申请的内存资源无法得到满足
用户手动终止用户通过命令行(kill命令)强制终止进程

总的来说会有下面三种退出场景:
1.代码运行完毕,结果正确
2.代码运行完毕,结果不正确
3.代码异常终止

三、进程终止的实现

我们结合相关代码,对上面的场景逐帧分析

3.1 程序退出码

在我们平时写的代码中,main函数内都会有依据return 0这表示着程序结束时返回0(不同的退出码代表不同的涵义),这个零就是我们所写程序的退出码,但是当我们所写的程序运行出错时,它往往会给我们返回一个非零值,这时什么意思呢?首先我们要知道程序退出码是干什么的:
程序退出码是程序终止时返回给操作系统的一个整数值,用于指示程序的执行结果。它的核心是为调用者提供清晰的状态反馈,以便后续处理。
更详细的内容我会在下文穿插介绍

3.2 运行完毕结果正常

return 终止进程

这是我们接触最多的一种方式:

  1 #include<stdio.h>2 int main()3 {4   printf("I am process...\n");                                                                                                    5   return 0;                                                                                                               6 } 

在这里插入图片描述

当我们执行这个程序后,我们只能看到程序运行的结果,程序退出码呢?其实程序退出码,返回是为了给他的父进程(这里的父进程就是bash命令行)查看的,父进程创建出子进程来执行程序时,它需要知道子进程执行的结果(如成功、错误等)程序退出码的作用就是反馈执行状态,通常退出码为零表示成功执行,而非零值,表示不同类型的错误。我们可以通过这个命令查看程序退出码:

echo $?

$?:保存的是最近一次进程退出时的退出码
在这里插入图片描述

exit终止进程

想了解更多可以通过man手册查看
在这里插入图片描述

exit(n)直接终止进程并返回一个指定的退出码,适用于需要立刻终止进程的场景:

  1 #include<stdio.h>  2 #include<stdlib.h>  3 #include<unistd.h>  4 void test()  5 {  6   printf("I am process...\n");  7   //int *ptr=(int*)malloc(1000*1000*4);  8   exit(11);9   printf("I am process...\n");                                                                               10 }                                                                                                            11 int main()                                                                                                   12 {                                                                                                            13   test();                                                                                                    14   return 0;                                                                                                  15 }         

在这里插入图片描述
可以看到当程序执行过,exit(11)后程序直接退出,并返回指定退出码,不再继续向下执行。
exitreturn的区别
在主函数中两者是等价的,但是在多层函数调用中,return只表示当前所处函数调用完成,而exit
则会直接终止进程并返回程序退出码,当我们的程序在被调用的函数中出错时,我们就可以使用exit直接终止程序而不是使用return返回主函数再终止,在后面我会给出示例。

_exit终止进程

在这里插入图片描述
这个系统调用接口和exit用法一样,但是不同的是:

  1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 void test()5 {6   printf("I am process...");                                                                                                      7   //int *ptr=(int*)malloc(1000*1000*4);8   _exit(11);9   printf("I am process...\n");10 }11 int main()12 {13   test();14   return 0;15 }

在这里插入图片描述
_exit在终止进程时,不会刷新缓冲区,而exit会帮助进程刷新缓冲区的资源
注:在测试这一点时打印函数不可以加\n\n会帮助我们刷新缓冲区资源。
在这里插入图片描述

3.3 运行完毕结果异常

strerror 函数

在介绍程序退出码时我们说,不同的退出码对应着不同错误信息,那么我们该如何知道退出码对应的错误信息呢?在库函数中存在strerror函数可以帮助我们:
下面代码打印出0~5程序退出码,所对应的信息。

  1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 #include<string.h>5 int main()6 {7   int i=0;8   for(;i<=5;i++)9   {10     printf("%d->%s\n",i,strerror(i));                                                                                             11   }12   return 0;13 }

在这里插入图片描述

errno 全局变量

在C/C++中给我们提供了一个全局,当程序执行错误时,系统会将变量值修改为对应的错误码,并返回(程序退出码),我们可以配合strerror函数之间打印出对应的错误信息:

     1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 #include<string.h>5 #include<errno.h>6 int main()7 {8   int *ptr=(int*)malloc(1000*1000*1000*4);9   if(ptr==NULL)10   {11     printf("malloc error,%d->%s\n",errno,strerror(errno));                                                                      12   }13   return 0;14 }

在这里插入图片描述

perror 函数

它就像一个简化版的strerror信息,可以直接输出错误描述,格式为:
用户自定义消息:错误描述
在这里插入图片描述

    1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 #include<string.h>5 #include<errno.h>6 int main()7 {8   int *ptr=(int*)malloc(1000*1000*1000*4);9   if(ptr==NULL)10   {11     perror("malloc error:");                                                                                                    12   }                                                                          13   return 0;                                                                  14 }              

3.4 程序异常退出

这里的原因还是比较多的,今天我们先介绍kill,我们可以使用kill系统调用或命令强制终止进程:

kill命令

  1 #include<stdio.h>  2 #include<stdlib.h>  3 #include<unistd.h>  4 #include<string.h>  5 #include<errno.h>  6 int main()  7 {  8   printf("I am prcsess......\n");                                                                                                 9   sleep(100);                                                                                                              10   return 0;                                                                                                               11 }   

在这里插入图片描述
这个好像不太好演示......

kill系统调用

在这里插入图片描述
第二个参数对应的信号可以通过kill -l查看

  1 #include<stdio.h>2 #include<stdlib.h>                                                                                                                3 #include<signal.h>4 #include<unistd.h>5 int main()6 {7   pid_t id=fork();8   if(id==0)9   {10     while(1)11     {12 13        printf("I am child,pid:%d,ppid%d\n",getpid(),getppid());14        sleep(1);15     }16   }17   else if(id>0)18   {19     sleep(5);20     kill(id,SIGKILL);21   }22   else exit(1);23   return 0;24 }

在这里插入图片描述

总结

进程终止是我们在学习Linux系统部分比较重要的一节,本篇我们主要介绍了进程退出码的作用以及如何来获取使用它,这对我们高效的编程有很大的帮助。

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

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

相关文章

正则表达式引擎深入探讨

正则表达式引擎&#xff08;Regular Expression Engine&#xff09;是正则表达式得以“活起来”的核心。它是一个精密的软件组件&#xff0c;负责接收正则表达式和输入文本&#xff0c;解析模式并执行匹配或替换操作&#xff0c;最终输出结果——可能是简单的“是否匹配”&…

java面试题,什么是动态代理?、动态代理和静态代理有什么区别?说一下反射机制?JDK Proxy 和 CGLib 有什么区别?动态代理的底层

什么是动态代理&#xff1f; 动态代理是在程序运行期&#xff0c;动态的创建目标对象的代理对象&#xff0c;并对目标对象中的方法进行功能性增强的一种技术。 在生成代理对象的过程中&#xff0c;目标对象不变&#xff0c;代理对象中的方法是目标对象方法的增强方法。可以理解…

【工具类】Java的 LocalDate 获取本月第一天和最后一天

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

嵌入式开发之STM32学习笔记day06

基于STM32F103C8T6的开发实践——从入门到精通01 1. 引言 STM32系列微控制器是STMicroelectronics推出的一款高性能、低功耗的32位微控制器&#xff0c;广泛应用于嵌入式系统中。STM32F103C8T6是其中非常受欢迎的一款&#xff0c;凭借其强大的性能、丰富的外设接口和低廉的价格…

学习使用 Git 和 GitHub 开发项目的教程推荐

Git 和 GitHub 是现代软件开发中不可或缺的工具&#xff0c;无论你是个人开发者还是团队成员&#xff0c;掌握它们都能极大提升效率。本文精选了一系列优质教程资源&#xff0c;涵盖从基本 Git 命令到进阶多人协作的内容。这些教程既有文字形式&#xff0c;也有视频或交互式资源…

golang中的接口

1.简介 在go中的接口是以一种类型,一种抽象的类型。接口(interface)是一组函数method的集合,go中的接口不能包含任何变量。在go中接口中的所有方法都没有方法体,接口定义了一个对象的行为规范,只定义规范不实现。接口体现了程序的多态和高内聚低耦合的思想。go中的接口也是…

AI 浪潮下,职场的变与不变

如今&#xff0c;AI 如迅猛飓风&#xff0c;极速席卷职场&#xff0c;彻底搅乱了原有的秩序。你是否留意到&#xff0c;身边的工作方式正悄然生变&#xff1f;今天&#xff0c;【探星 AI 研习社】就为大家深入剖析&#xff0c;AI 如何改写职场剧本。无论你是大学生还是职场资深…

汇川EASY系列之以太网通讯(MODBUS_TCP做主站)

汇川Easy系列以太网通讯中(MODBUSTCP,plc做主站),终于可以不用使用指令就可以完成了,全程通过简单的配置就可通讯。本文将通过EASY系列PLC与调试助手之间完成此操作。具体演示如下; 关于主站和从站的介绍 A/请求:即主动方 向被动方发送的一个要求的信息。 B/主站:发…

npm error gyp info

在使用 npm 安装 Node.js 包时&#xff0c;可能会遇到各种错误&#xff0c;其中 gyp 错误是比较常见的一种。gyp 是 Node.js 的一个工具&#xff0c;用于编译 C 代码。这些错误通常发生在需要编译原生模块的 npm 包时。下面是一些常见的原因和解决方法&#xff1a; 常见原因及…

Oracle 19C分区表索引小结

一、大佬说&#xff08;杨廷琨&#xff09; LOCAL索引的最大好处是在进行分区操作&#xff0c;比如TRUNCATE PARTITION, DROP PARTITION时&#xff0c;不会出现索引INVALID的情况&#xff0c;不影响索引的可用性。由于GLOBAL索引所有的数据存储在一起&#xff0c;因此当执行分…

AutoHub场景演示|带您领略智能自动化操作的全新体验

AutoHub是一款由OpenCSG推出的基于前沿大型语言模型&#xff08;LLM&#xff09;的浏览器自动化工具&#xff0c;旨在通过智能对话交互和自动化技术&#xff0c;帮助用户更高效地浏览网页和完成任务。它不仅能够自动化繁琐的网页操作&#xff0c;还能够为用户提供精准的信息检索…

深入解析 Linux 声卡驱动:从架构到实战

在嵌入式 Linux 设备中&#xff0c;音频功能的实现离不开 Linux 声卡驱动。而 ALSA (Advanced Linux Sound Architecture) 作为 Linux 内核的音频框架&#xff0c;提供了一整套 API 和驱动模型&#xff0c;帮助开发者快速集成音频功能。本篇文章以 WM8960 音频编解码器&#xf…

thinkphp5模型查询数据库,查出来的字段直接修改成另外的名字

在ThinkPHP5中,如果你希望在查询数据库时将返回的字段名直接修改为其他名称,可以通过以下几种方式实现: 方法1:使用 field 方法指定字段别名 在查询时通过 field 方法直接为字段指定别名(使用 AS 关键字)。 示例代码: // 使用Db类查询 $result = Db::name(user)->…

关于前端指令

在前端开发中&#xff0c;指令&#xff08;Directives&#xff09;通常指在框架中使用的一种特殊的语法或机制&#xff0c;用于扩展 HTML 的功能。常见的指令主要存在于前端框架中&#xff0c;如 Vue.js、Angular 等。下面我们将分别介绍 Vue.js 和 Angular 中的常用指令&#…

虚拟地址空间(下)进程地址空间(上)

一.关于页表组成 1.权限&#xff08;rwx) 作用&#xff1a;如1.让代码区变成只读的 2.写时拷贝的实现&#xff1a;子进程创建时其页表指向的父进程代码和数据权限都是只读的&#xff0c;子进程试图修改&#xff0c;触发错误&#xff0c;系统开始写时拷贝。 来源&#xff1a;…

【区块链 + 航运物流】丰溯 - 区块链溯源平台 | FISCO BCOS 应用案例

丰溯是顺丰科技推出的区块链溯源平台&#xff0c; 采用 FISCO BCOS 底层开源框架&#xff0c; 为农副食品、 冷链生鲜等企业客户及消费 者提供关键流通节点的溯源信息服务&#xff0c;形成从源头到消费者端全链路透明的信息链。 在商贸消费领域&#xff0c; 溯源一直是保障产品…

iwebsec-SQL数字型注入

1.判断是否存在漏洞 添加and 11发现正常显示&#xff0c;添加and 12无回显条目&#xff0c;则存在sql注入漏洞 2.因为有回显&#xff0c;尝试union联合注入&#xff0c;使用order by判断出有3个字段 3.使用union联合注入查看回显位&#xff0c;发现3三个字段均有回显&#xff…

蓝桥杯每日五题第一日

蓝桥杯每日5题 问题一 班级活动 1.班级活动 - 蓝桥云课 问题描述 小明的老师准备组织一次班级活动。班上一共有 nn 名 (nn 为偶数) 同学&#xff0c;老师想把所有的同学进行分组&#xff0c;每两名同学一组。为了公平&#xff0c;老师给每名同学随机分配了一个 nn 以内的正…

STM32 —— 嵌入式系统、通用计算机系统、物联网三层架构

目录 一、嵌入式系统的概念 二、通用计算机系统与嵌入式系统的比较 用途 硬件 软件 性能与功耗 开发与维护 三、嵌入式系统与物联网的关系 四、物联网的三层架构 1. 感知层&#xff08;Perception Layer&#xff09; 2. 网络层&#xff08;Network Layer&#xff09; …

卡码网25题——掌握ACM输入输出方式(15 至 18)

刷题小记&#xff1a; 本期涉及ACM模式下栈和链表的构建与使用&#xff0c;值得学习。 卡玛网15.神秘字符&#xff08;卡玛网15.神秘字符&#xff09; 题目分析&#xff1a; 若给定2行字符串&#xff0c;其中第一个串的长度为偶数&#xff0c;现要求把第二个串插入到第一个…