【Linux】进程终止

devtools/2024/10/18 16:47:14/

思维导图

学习内容

       进程终止是进程控制里面的一个重要的知识,通过这一篇博客,我们可以学习到进程终止的概念,进程终止的三种情况,进程终止的退出码和退出信号,最后在来学习进程是如何进行终止的。

学习目标

一、进程终止的概念

       在计算机系统中,进程是操作系统分配资源的基本单位,而进程终止则是指操作系统因为某种原因结束一个进程的执行。这可能是因为进程完成了某种任务,也可能是因为出现了错误或异常。

       创建一个进程的过程是:先创建一个内核的部分数据结构,再进行复制代码和数据。那么终止一个进程的过程是和创建一个进程的顺序是相反的,终止一个进程的本质是:释放曾经的代码和数据所占据的空间,释放内核数据结构。

二、echo 内建命令

       echo内建命令的概念:打印的是bash内部的变量数据。

       ?符号的意义:父进程bash获取到最近一个子进程退出的退出码,0表示正常退出,非0表示异常退出。这个返回值需要让父进程得到,告诉父进程,子进程将任务完成的怎么样。

       不是?符号可以将最近一个子进程退出的退出码获取吗?但是上图中为什么获取了两个不同的子进程退出的退出码。 

       因为echo命令也是一个进程,当使用完echo命令后,变成了最近一次子进程,又因为echo命令正常退出,所以最近一次子进程退出的退出码是0。

三、进程退出码

3.1 strerror函数

3.1.1 strerror函数的用途获取指向错误信息字符串的指针。

3.1.2 strerror函数的介绍

#include <string.h>
char* strerror(int errnum)
// 返回值为char * 类型,指向描述错误错误的错误字符串的指针

3.1.3 利用strerror函数来获取C语言中所有的错误信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int errcode = 0;for(errcode = 0; errcode <= 255; errcode++){printf("%d %s\n", errcode, strerror(errcode));}return 100;
}

3.2 父进程为什么要获取子进程的退出码?

       因为父进程要知道子进程完成任务的情况(成功或者失败,失败的原因是什么),要对子进程进行负责。

3.3 自定义退出码

       我们可以通过联合体为自定义退出码进行赋值,将退出码置为全局变量,在每一个函数的每一种结果中都需要将退出码进行修改,在通过接收退出码的值将退出码的值翻译为错误信息的字符串。

#include <stdio.h>enum{Success = 0,Div_Zero,Mod_Zero,
};int errcode = Success;int Div(int a, int b)
{if(b == 0){errcode = Div_Zero;return -1;}else{errcode = Success;return a / b;}
}char* geterror(int errno)
{switch(errno){case Success:return "Success";case Div_Zero:return "Div_Zero";case Mod_Zero:return "Mod_Zero";dafault:return NULL;}
}int main()
{int tmp1 = Div(10, 1);printf("answer: %d Error: %s\n", tmp1, geterror(errcode));int tmp2 = Div(10, 0);printf("answer: %d Error: %s\n", tmp2, geterror(errcode));return 0;
}

四、进程终止的三种情况

4.1 通过进程的退出码决定的进程终止的情况

  • 代码跑完,结果正确
  • 代码跑完,结果不正确

4.2 通过进程的退出信号决定的进程终止的情况 

最后一种情况:代码执行时,出现了异常,提前退出了,退出码没有意义。

  • 编译运行时,崩溃了,操作系统发现了你的进程做了不该做的事情,操作系统杀死了进程。
  • 一旦进程出现异常,退出码没有意义

进程异常的退出信号

我们可以使用kill命令来显示进程异常的退出信号所代表的含义:

kill -l

现在我们可以通过做个实验,来查看进程异常退出是否需要错误信号。

#include <stdio.h>
#include <unistd.h>int main()
{while (1){printf("I am process, pid = %d\n", getpid());sleep(1);}return 0;
}

当代码中出现一些异常错误时,进程也会发出错误信号,杀死进程。

总结:判断一个进程的退出情况,我只需要检查进程是否出现异常;如果没有出现异常,就检查进程的退出码。衡量一个进程退出,我们只需要两个数字:退出码和退出信号

五、进程如何终止

  • main函数调用return表示进程终止(普通函数的return,是退出函数)
  • 代码调用exit函数,在进程退出后,会冲刷缓冲区
  • 系统调用_exit函数,在进程退出后,不会冲刷缓冲区

我们可以通过代码来观察现象:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{printf("Hello world");exit(1);return 0;
}

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{printf("Hello world");_exit(1);return 0;
}


http://www.ppmy.cn/devtools/27831.html

相关文章

2024年第二十六届“华东杯”(A题)大学生数学建模挑战赛|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看华东杯 (A题&#xff09;&#xff01; 问题一&a…

CSS_sass模块化、scss模块化

import 1、运行时语法&#xff1a; import url(xxxxxx.css); // 编译后 import url(xxxxxx.css);2、编译时语法&#xff1a; 编译后&#xff1a;生成的css文件就会包含common.scss里面的代码,自然可以使用common里面的css变量 // common.scss $color: redimport "./com…

【ARM Cache 系列文章 11.1 -- ARM Cache 全相连 详细介绍】

请阅读【ARM Cache 系列文章专栏导读】 文章目录 Cache 全相连(Fully Associative)全相联映射示例全相联映射原理紧接文章:【ARM Cache 系列文章 11 – ARM Cache 组织形式详细介绍】 Cache 全相连(Fully Associative) 介绍: 在全相连缓存中,任何内存地址都可以缓存在 …

github的注册和使用

注册 GitHub 账号 打开 GitHub 官方网站&#xff1a;https://github.com/点击页面右上角的“Sign up”按钮。输入你的邮箱地址、选择一个用户名、设置密码。同意 GitHub 的使用协议。点击“Sign up for GitHub”完成注册。 设置 GitHub 登录后&#xff0c;你可以设置个人的头…

GAI工具哪家强?(ChatGPT 4 vs 文心一言)

开始之前&#xff0c; 先来看看 GAI和AI的区别和关系。 AI 和GAI AI 和GAI的概念 AI&#xff08;Artificial Intelligence&#xff09;是人工智能的缩写&#xff0c;是计算机科学的一个分支&#xff0c;旨在使机器像人类一样进行学习和思考。AI技术的研究领域包括机器人、语…

Linux系统SSH远程管理服务

一、SSH服务介绍 1.1什么是SSH SSH (Secure Shell)是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。 SSH协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令&#xff0c;SSH为建 立在应用层和传输层基础上的安全协…

springaop实现相关功能(事务、异常处理、记录日志)

springaop的底层实现&#xff08;代理模式&#xff09; 原理设计 代理模式&#xff1a; Spring AOP使用了代理模式&#xff0c;为目标对象创建一个代理对象。当调用目标对象的方法时&#xff0c;实际上是调用代理对象的方法。代理对象在调用目标方法前后&#xff0c;可以插入额…

使用FPGA实现串-并型乘法器

介绍 其实我们知道&#xff0c;用FPGA实现乘法器并不是一件很简单的事&#xff0c;而且在FPGA中也有乘法器的IP核可以直接调用&#xff0c;我这里完全就是为了熟悉一些FPGA的语法然后写了这样一个电路。 串-并型乘法器模块 从字面上看&#xff0c;串-并乘法器就是其中一个乘数…