【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…

Navicat 基础操作和 SQL 语句详解

Navicat 是一个流行的数据库管理工具&#xff0c;支持多种数据库&#xff08;如MySQL、MariaDB、SQL Server、PostgreSQL等&#xff09;。在Navicat中&#xff0c;你可以通过GUI界面来管理数据库&#xff0c;也可以直接编写SQL语句。下面我将介绍如何在Navicat中执行一些基础的…

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

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

day10:ssh服务-跳板机

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

表达式求值(2020cspj)

题目描述 给定一个只包含加法和乘法的算术表达式&#xff0c;请你编程计算表达式的值。 输入格式 一行&#xff0c;为需要你计算的表达式&#xff0c;表达式中只包含数字、加法运算符 和乘法运算符 *&#xff0c;且没有括号&#xff0c;所有参与运算的数字均为 0 到 231−1…

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 ~/…

#渗透测试#安全见闻7 硬件设备的网络安全问题与潜在漏洞分析

安全见闻7 硬件设备的网络安全问题与潜在漏洞分析及渗透测试应用 ##B站陇羽Sec## 硬件设备在网络系统中扮演着至关重要的角色&#xff0c;它们构成了网络的物理基础&#xff0c;确保数据能够有效地传输和处理。以下是几种关键的硬件设备及其在网络中的作用&am…

mysql8数据库备份

1、背景 mysql 8备份策略&#xff0c;备份7天&#xff0c;每天全量备份一次。 2、方案 在 MySQL 8 中&#xff0c;你可以使用 mysqldump 工具来创建数据库的全量备份。要实现每天全量备份一次&#xff0c;并且保留最近7天的备份&#xff0c;你可以设置一个自动化的备份策略&am…

C# 串口通信教程

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

2024Flutter面试题

1.Dart是值传递还是引用传递&#xff1f; dart是值传递。 每次调用函数&#xff0c;传递过去的都是对象的内存地址&#xff0c;而不是这个对象的赋值。 2.简述Dart语音特性 在Dart中&#xff0c;一切都是对象&#xff0c;所有的对象都是继承自Object Dart是强类型语言&#…

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;门店…

gin入门教程(4):路由与处理器

路由与处理器 在 Gin 框架中&#xff0c;路由和处理器是核心组成部分&#xff0c;负责将 HTTP 请求映射到相应的处理逻辑。 1. 定义路由 在 cmd/main.go 中&#xff0c;您可以定义不同的路由&#xff0c;例如&#xff1a; r.GET("/ping", func(c *gin.Context) {…

.NET 8 Web API从基础到提高全面示例

.NET 8 Web API从基础到提高全面示例 概述&#xff1a;1. 设置 .NET 8 Web API 项目概念使用 .NET CLI 创建新的 Web API 项目。这设置了一个基本的项目结构&#xff0c;包括启动和 WeatherForecast 控制器作为示例。Program.cs代码示例dotnet new webapi -n MyWebApi2. Prog…