【Linux系统】进程终止




在这里插入图片描述



一、进程退出方式


1、正常终止

主要两种类型:从 main 返回、调用 exit _exit

具体讲解如下:


(1)从 main 返回

这个的使用就不用多说了吧,相信你们已经烂熟于心了

  • 作用return 语句用于从函数中返回一个值,并终止该函数的执行。在 main 函数中,return 语句用于终止整个程序的执行,并返回一个状态码给操作系统。
  • 范围return 仅在函数内部有效,不能从全局作用域或其他地方使用。
  • 清理工作:在 main 函数中使用 return 时,会执行标准 I/O 缓冲区的刷新、关闭打开的文件描述符等清理工作,也会调用在 atexit 注册的函数。

执行 return x 等同于执行 exit(x),因为调用 main 的运行时函数会将 main 的返回值当做 exit 的参数。

exit 函数如何使用,看下文解释:



(2)调用 exit _exit

这两个系统调用函数可以立即终止整个程序的执行,但是他们两还是有不少区别的,这篇博客有更加详细的讲解:【Linux】 exit 和 _exit 的区别-CSDN博客


(3)returnexit 的异同点

作用范围

  • return :仅在函数内部有效,主要用于从函数中返回一个值。
  • exit_exit :可以在程序的任何地方调用,用于立即终止整个程序的执行。

清理工作

  • returnexit :都会执行标准 I/O 缓冲区的刷新、关闭打开的文件描述符等清理工作,并调用在 atexit 注册的函数。


2、异常终止


引入:ctrl + c

我们常常通过 ctrl + c 使当前正在执行的进程停下,其背后的原理是:

ctrl + c :信号终止,被强行杀掉

当用户在终端中按下 Ctrl+C 时,会向当前的前台进程发送 SIGINT(Interrupt)信号。这个信号通常用于中断或请求终止正在运行的程序。



正文如下

​ 进程因为异常而中断退出的情况通常是指由于某些内部错误或外部事件导致进程无法继续执行,从而被迫终止。OS提前使用信号终止你的进程,下面是几种常见的异常情况及其原因:

(1) 访问非法内存地址(Segmentation Fault)

即为 野指针 问题

当进程试图访问不允许访问的内存区域时,会触发 SIGSEGV 信号,导致进程被中断并退出。

示例代码
#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = NULL;*ptr = 42;  // 尝试访问空指针指向的内存return 0;
}


(2) 除零错误(Division by Zero)

当进程执行除法运算时除数为零,会触发 SIGFPE 信号,导致进程被中断并退出。

示例代码
#include <stdio.h>
#include <stdlib.h>int main() {int result = 1 / 0;  // 除零错误return 0;
}


(3)系统调用失败

当进程执行某些系统调用时发生错误,可能会导致进程异常退出。例如,打开文件失败、创建文件失败等情况。

示例代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {perror("open");return EXIT_FAILURE;}close(fd);return 0;
}


(4)文件权限问题

当进程试图访问没有权限访问的文件时,会触发 SIGBUSSIGSEGV 信号,导致进程被中断并退出。

示例代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>int main() {int fd = open("/root/protected_file.txt", O_RDONLY);if (fd == -1) {perror("open");return EXIT_FAILURE;}close(fd);return 0;
}


(5) 进程被杀死

当进程被其他进程或管理员使用 kill 命令发送 SIGKILL 信号时,进程会被强制终止,而不会执行任何清理工作。

示例命令
kill -9 <PID>


总结

进程因为异常而中断退出的情况包括但不限于:

  • 访问非法内存地址(野指针):尝试访问不允许访问的内存区域,触发 SIGSEGV 信号。
  • 除零错误:执行除法运算时除数为零,触发 SIGFPE 信号。
  • 系统调用失败:执行某些系统调用时发生错误,导致进程异常退出。
  • 文件权限问题:试图访问没有权限访问的文件,触发 SIGBUSSIGSEGV 信号。
  • 进程被杀死:被其他进程或管理员使用 SIGKILL 信号强制终止。

了解这些异常情况及其原因有助于更好地调试和优化程序,确保进程能够在各种环境下稳定运行。



二、进程退出码的获取

1、退出状态码的作用

前面讲解过,无论是通过 return exit/_exit 正常退出,还是被信号终止或停止的异常退出,进程退出都会返回一个退出状态码给父进程,用于告知父进程:我这个退出的子进程是否正确执行任务,如果是异常退出,我又是因为什么原因退出的。

这个状态码包含了关于子进程退出原因的重要信息,父进程可以通过解析这个状态码来了解子进程的退出情况。




2、退出状态码是 16 位的整数

在 Unix 和 Linux 系统中,退出状态码通常是一个 16 位的整数,其中高 8 位和低 8 位分别包含不同的信息:

  • 低 8 位:表示子进程的退出状态码(0-255)。对于正常退出,这是 returnexit 传递的值。
  • 高 8 位:包含其他信息,如终止信号编号等。

如下图的两行长方形,代表着两种进程退出时退出状态码的各个部分的作用:正常终止、被信号所杀

在这里插入图片描述




3、进程退出码的来源

当子进程终止时,操作系统会记录子进程的退出状态码,并将其保存在子进程的进程控制块(PCB)中。

父进程调用 waitwaitpid 时,操作系统会将子进程的退出状态码返回给父进程。

进程退出码并不是通过我们下面几条程序代码函数返回的,而是操作系统负责返回的,

我们下面几条程序要做的是设置与修改进程退出状态码,而不负责退出码返回。



(1)子进程正常退出:

当进程正常退出时,操作系统会设置退出状态码为 returnexit/_exit 传递的值。

  • main 函数 return status 返回:默认返回值为 0(表示成功退出)
  • exit(int status) 返回
  • _exit(int status) 返回

(一个进程只要是通过 exit 或 _exit函数直接退出的,就算做正常退出!)



(2)子进程异常退出:

当进程因接收到信号而终止时,操作系统会设置退出状态码的高 8 位为信号编号,低 8 位通常为 0。



4、如何获取进程退出码

而我们可以通过一些系统宏定义来获取进程的退出状态码,本篇博客中有这些宏定义的使用与使用示例:【Linux】如何通过系统宏定义,获取进程的退出码或退出信号-CSDN博客

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

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

相关文章

一篇文章了解RocketMQ基础知识。

目录 一. 为什么选择了 RocketMQ &#xff1f; 二. RocketMQ 介绍 名词说明 1. Topic (主题) 1.1 Topic 核心作用 1.2 Topic 常见问题 2. Tag (标签) 3. Queue (队列) 3.1 Queue 读写队列 4. Message &#xff08;消息&#xff09; 4.1 Message 类型 5. Produ…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备视频报警功能详解

在科技日新月异的今天&#xff0c;视频监控系统作为现代社会的“第三只眼”&#xff0c;正以前所未有的方式深刻影响着我们的生活与社会结构。从公共场所的安全监控到个人生活的记录分享&#xff0c;视频监控系统以其独特的视角和功能&#xff0c;为社会带来了诸多好处&#xf…

day10:ssh服务-跳板机

一&#xff0c;ssh服务概述 ssh服务概述 ssh&#xff08;Secure Shell&#xff09;是一种用于在不安全网络中进行安全登录、远程执行命令及传输文件的网络协议。它通过加密技术来保证通信的保密性和完整性&#xff0c;主要用于替代不安全的telnet、rlogin、rsh等协议。ssh通常…

python爬虫实战案例——抓取B站视频,不同清晰度抓取,实现音视频合并,超详细!(内含完整代码)

文章目录 1、任务目标2、网页分析3、代码编写 1、任务目标 目标网站&#xff1a;B站视频&#xff08;https://www.bilibili.com/video/BV1se41117WP/?vd_sourcee8e376ccbc5aa4cfd88e6a7917adfd1a&#xff09;&#xff0c;用于本文测验 要求&#xff1a;抓取该网址下的视频&…

【制造业&电子产品】电脑电子元件检测系统源码&数据集全套:改进yolo11-TADDH

改进yolo11-SCConv等200全套创新点大全&#xff1a;电脑电子元件检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.24 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者…

Linux: network: wireshark IO图的一个问题

今天遇到一个问题&#xff0c;发现wireshark画的IO图&#xff0c;前几秒没有数据&#xff0c;但是根据Raw的pcap看&#xff0c;是有包的&#xff0c;这就迷惑了。 经同事提醒&#xff0c;这个IO在设置了多个画图filter的时候&#xff0c;可能导致开始前几秒没有输出。如下图 这…

jenkins ssh 免密报错Host key verification failed.

jenkins 发布项目&#xff0c;ssh连接远程服务器时报错&#xff1a;Host key verification failed. 解决&#xff1a; 原因是生成的sshkey不是用的jenkins用户&#xff0c;所以切换用户到&#xff1a;jenkins重新生成sshkey su jenkins ssh-keygen -t rsa ssh-copy-id -i ~/…

C# 串口通信教程

串口通信&#xff08;Serial Communication&#xff09;是一种用于设备之间数据传输的常见方法&#xff0c;通常用于与外部硬件设备&#xff08;如传感器、机器人、微控制器&#xff09;进行通信。在 C# 中&#xff0c;System.IO.Ports 命名空间提供了与串口设备交互的功能&…

mono源码交叉编译 linux arm arm64全过程

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

GPT-4o 和 GPT-4 Turbo 模型之间的对比

GPT-4o 和 GPT-4 Turbo 之间的对比 备注 要弄 AI &#xff0c;不同模型之间的对比就比较重要。 GPT-4o 是 GPT-4 Turbo 的升级版本&#xff0c;能够提供比 GPT-4 Turbo 更多的内容和信息&#xff0c;但成功相对来说更高一些。 第三方引用 在 2024 年 5 月 13 日&#xff0…

8.MySQL复合查询

目录 复合查询基本查询回顾多表查询 - 笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from中使用子查询 合并查询unionunion all 表的内连和外连内连接外连接左外连接右外连接 复合查询 前面我们讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远…

HTML+JavaScript案例分享: 打造经典俄罗斯方块,详解实现全过程

在本文中,我们将深入探讨如何使用 JavaScript 实现经典的俄罗斯方块游戏。俄罗斯方块是一款广为人知的益智游戏,通过操纵各种形状的方块,使其在游戏区域内排列整齐,以消除完整的行来获得分数。 效果图如下: 一、游戏界面与布局 我们首先使用 HTML 和 CSS 来创建游戏的界面…

java智能物流管理系统源码(springboot)

项目简介 智能物流管理系统实现了以下功能&#xff1a; 智能物流管理系统的主要使用者分为管理员&#xff0c;顾客&#xff0c;员工&#xff0c;店主。功能有个人中心&#xff0c;顾客管理&#xff0c;员工管理&#xff0c;店主管理&#xff0c;门店信息管理&#xff0c;门店…

查看Chrome安装路

谷歌Google浏览器查看安装路径&#xff0c;浏览器Google Chrome浏览器查看安装路径 chrome://version/ 来源&#xff1a;笔记云

idea安装visualVm插件

idea 安装visualVM插件用于分析java程序&#xff0c; 1.在插件市场安装visualvm launcher 2.安装成功后&#xff0c;重启idea&#xff0c;此时启动按钮旁边有这两个按钮 3.需要在这里配置插件的visualvm位置 4.配置完后&#xff0c;点击启动

已解决 django.db.utils.OperationalError: (1051, “Unknown table

报错信息&#xff1a; django.db.utils.OperationalError: (1051, "Unknown table bjybolg.tool_submission")python manage.py migrate --fake 命令用于告诉 Django 假装已经应用某个迁移&#xff0c;而不实际执行该迁移的操作。这通常在以下情况下非常有用&#x…

Layout 布局组件快速搭建

文章目录 设置主题样式变量封装公共布局组件封装 Logo 组件封装 Menu 菜单组件封装 Breadcrumb 面包屑组件封装 TabBar 标签栏组件封装 Main 内容区组件封装 Footer 底部组件封装 Theme 主题组件 经典布局水平布局响应式布局搭建 Layout 布局组件添加 Layout 路由配置启动项目 …

Linux: Shell编程入门

Shell 编程入门 1 ) Shell 概念 shell 是 在英语中 壳, 外壳的意思可以把它想象成嵌入在linux这样的操作系统里面的一个微型的编程语言不像C语言, C 或 Java 等编程语言那么完整&#xff0c;它可以帮我们完成很多自动化任务例如保存数据监测系统的负载等等&#xff0c;我们同样…

【ArcGIS Pro实操第8期】绘制WRF三层嵌套区域

【ArcGIS Pro实操第8期】绘制WRF三层嵌套区域 数据准备ArcGIS Pro绘制WRF三层嵌套区域Map-绘制三层嵌套区域更改ArcMap地图的默认显示方向指定数据框范围 Map绘制研究区Layout-布局出图 参考 本博客基于ArcGIS Pro绘制WRF三层嵌套区域&#xff0c;具体实现图形参考下图&#xf…

从零开始学五笔(七):折区字根

讲解格式&#xff1a; 先介绍按键的区位号、口诀内容、口诀说明然后列每个字根能组成什么汉字&#xff0c;难拆字将用中括号标出 ‍ N 键 区位号&#xff1a;51 口诀&#xff1a;已半巳满不出己&#xff0c;左框折尸心和羽 说明&#xff1a; 已半巳满不出己&#xff1a;指…