《Linux从练气到飞升》No.18 进程终止

🕺作者: 主页

我的专栏
C语言从0到1
探秘C++
数据结构从0到1
探秘Linux
菜鸟刷题集

😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!

前言

前面我们讲述了使用fork函数进行进程的创建,既然有创建就有终止,那么本篇将向大家讲述进程终止的相关知识~

进程终止与操作系统

进程终止时操作系统做了什么呢?当然是要释放进程申请的相关内核数据结构和对应的数据和代码。本质就是释放系统资源。

进程退出场景

进程退出有三种场景如下:

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止

这里我们要展开讲一下。在我们使用c语言进行编程的时候,我们会注意到main函数的返回值,总是return 0,为什么总是0呢?因为他是进程的退出码 。那他一定得是0吗?并不是的。他返回这个数字的意义在于返回给你上一级进程,用来评判该进程执行结果用的 。如果非零值就说明是,程序是有错误的,非零值有无数个,不同的非零值就可以标识不同的错误原因,所以它的作用就是在我们的程序运行结束之后,结果不正确,可以方便我们定位错误的原因细节。

举个例子:

测试代码:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main()
{
    int a[3]={0};
    printf("%d\n",a[1])//注意看,这里少了个 ;
    return 0;
}

这里还要介绍一个指令,它可以查看上一个进程运行错误的原因

bash 复制代码
echo $?

返回2

是什么意思呢?别急!

我们先来查看一下这些"非零值"都代表着什么?

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
    for(int number = 0; number < 150; number++)
    {
        printf("%d: %s\n", number, strerror(number));//将数字代表的错误原因展示出来
    } 

    return 0;
}

查看结果:

进程常见退出方法

正常终止(可以通过 echo $? 查看进程退出码):

    1. 从main返回
    1. 调用exit
    1. _exit

异常退出:

  • ctrl + c,信号终止

_exit函数

bash 复制代码
#include <unistd.h>
void _exit(int status);
参数:status 定义了进程的终止状态,父进程通过wait来获取该值

说明:虽然status是int,但是仅有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$?发现返回值是255。

exit函数

bash 复制代码
#include <unistd.h>
void exit(int status);

exit最后也会调用_exit, 但在调用_exit之前,还做了其他工作:

  1. 执行用户通过 atexit或on_exit定义的清理函数。

  2. 关闭所有打开的流,所有的缓存数据均被写入

  3. 调用_exit

测试一下:

exit函数

cpp 复制代码
#include<stdio.h>
#include <stdlib.h>
int main()
{
    printf("hello");
    exit(0);
}

运行:

_exit函数

cpp 复制代码
#include<stdio.h>
#include <stdlib.h>
int main()
{
    printf("hello");
    _exit(0);
}

运行:

因为我们设置的字符串后面没有"\n",也就是说它会待在缓冲区中,然后我们会发现**_exit** 函数会直接结束,而exit 函数则是先把缓存区内的数据冲刷出来才结束,其实exit是库函数 ,而**_exit是系统接口**,exit函数最后会调用操作系统的_exit函数。

这里给大家留下一个问题,printf------\n数据保存在缓冲区中的,请问缓冲区在哪里?谁维护? 但是我们知道它一定不在操作系统内部,如果是操作系统维护的,缓冲区_exit就一定能够刷出来! 今天我只能告诉你是C语言标准库给我们维护的。懂得的小伙伴可以在评论区打出一起交流~

return退出

return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值当做 exit的参数。

后记

本篇我们主要讲述了进程的退出场景,进程的终止,正常情况下它有三种退出的方式,异常情况可以使用ctrl+c的方式终止~

相关推荐
不知更鸟1 小时前
Django 项目设置流程
后端·python·django
我是小超人-雨石花3 小时前
Jenkins&Robot Framework持续集成
运维·jenkins·ci
黄昏恋慕黎明3 小时前
spring MVC了解
java·后端·spring·mvc
wanhengidc4 小时前
云手机的软件核心是什么
运维·服务器·web安全·游戏·智能手机
G探险者5 小时前
为什么 VARCHAR(1000) 存不了 1000 个汉字? —— 详解主流数据库“字段长度”的底层差异
数据库·后端·mysql
百锦再5 小时前
第18章 高级特征
android·java·开发语言·后端·python·rust·django
Tony Bai5 小时前
Go 在 Web3 的统治力:2025 年架构与生态综述
开发语言·后端·架构·golang·web3
芬加达5 小时前
jvm八股
运维·服务器·jvm
小兔薯了5 小时前
11. Linux firewall 防火墙管理
linux·运维·服务器
程序猿20235 小时前
项目结构深度解析:理解Spring Boot项目的标准布局和约定
java·spring boot·后端