【linux进程控制(一)】进程终止--如何干掉一个进程?

简介: 【linux进程控制(一)】进程终止--如何干掉一个进程?

1. 前言

从这篇文章开始,将学习有关进程

控制的内容,包括:进程终止,进程等待

和进程的程序替换,内容不多,难度中等

请同学们耐心学习!

比起直接在界面输入CTRL+C
来终止一个进程外,我们更喜欢使用
一些函数接口(系统接口)来控制进程退出
一个进程的退出分为正常退出和异常退出

本章重点:

本篇文章着重讲解进程退出时
的三种场景以及常见的退出方法,
并且对比C库函数exit和系统调用
函数_exit的区别与联系.最后我们将
使用信号来模拟一些非正常退出的情况


2. 文章整体结构脉络

我们先把整篇文章的结构梳理出来

首先进程有三个退出场景:

  • 代码执行完,结果正确
  • 代码执行完,结果不正确
  • 代码异常终止了

第一,二种退出场景都是
属于正常退出的范围,正常退出
又有以下常见的方法:

  • 从main函数返回
  • 调用exit终止进程
  • 调用_exit终止进程

第三种退出场景是异常退出
异常退出往往是信号导致的,
我们熟悉的一个信号有:

  • CTRL+c,信号终止进程

全片文章将围绕以上内容做讲解!


3. 从main函数return进程

我们之前写C/C++代码时总会在写了

int main后写return 0,但是程序只能

return 0吗?答案是肯定不是!

先给出两个结论:

  1. 结论一:
  • 非main函数执行到return语句时
    代表此函数执行完毕!

  • main函数执行到return语句时
    代表此进程执行完毕!

  1. 结论二:
  • 程序正常执行完毕并且结果
    正确时返回0

  • 程序正常执行完毕但结果不正确
    时返回非0

有一个问题浮现在我们眼前,既然
结果不正确的返回值是非0,但是
非0有很多值,1,2,3,4,5等等,它们
分别有什么含义呢?不懂就去验证!

在验证前首先要明白一个函数:

它可以将错误码转换为错误字符串

int main()    
{    
    int i=0;    
    for(i=0;i<200;i++)                                                                                                                                                  
    {    
        printf("[%d]: %s\n",i,strerror(i));    
    }    
    return 0;    
}

不出所料,0对应成功!,

并且在134号错误以后,就是 未知错误了

查看最近进程的退出码:

使用指令: echo $?

写个代码,直接return来测试一下:

int main()
{
  return 66;
}


4. 使用库函数exit终止进程

exit的参数即为错误码,和main函数

的return值是一个意思

exit函数和return的区别:

  • return只有在main中使用时才
    代表此进程退出

  • exit函数在程序任一地方使用都
    可以直接退出程序,并且返回错误码

写一段代码验证一下:

void test1()
{
  exit(10);
}
void test2()
{
  exit(20);
}
int main()
{
  test1();
  exit(50);
  test2();
  return 0;
}

这里使用echo $?明显打印

出来的退出码是10!


5. 系统调用_exit和exit的区别

我们查看man的二号手册

可以看见_exit系统调用:

它和exit一样都是终止进程

并且_exit的参数也代表错误码

那么它们两个有什么区别呢?

我使用下面两段代码来验证:
一段用exit一段用_exit:

代码一:
  printf("你可以看见我吗?");
  sleep(1); //睡眠一秒
  exit(10);
代码二:
  printf("你可以看见我吗?");
  sleep(1); //睡眠一秒
  _exit(10);

下面两个图片对应运行结果:

直接看图片效果不是很好,这里建议

同学们自己去打一下这段代码

现象: 第一个打印了文字,而第二个没有打印

我们知道,printf打印的数据如果不使用
\n换行的话,数据会被存储到缓冲区里,
暂时不会打印出来,然而使用exit函数
结束进程后,缓冲区的数据被打印出来了
所以可以得出结论:exit函数会帮助我们
刷新缓冲区的数据,然而_exit函数不会

小思考:

既然exit是C语言提供的库函数
而_exit是操作系统提供的系统调用
_exit无法刷新缓冲区是不是说明缓冲区
压根就不在操作系统内?也就是说缓冲区
不由操作系统来维护,而是由C标准维护?

答案是,正确的!


6. 进程异常终止的场景

当我们在命令行输入CTRL+C传递

信号杀掉程序时,这是异常终止.

当程序中出现使用野指针或数组越界写入

时,程序会崩溃,崩溃也是进程异常结束

比如:

情况一:
int* p = NULL;
*p = 20;
情况二:
int a[10]={0};
a[11]=10;

此时运行程序后,程序会退出
这时候再去使用指令:echo $?
就没有意义了!

程序异常崩溃,退出码无意义
这是因为一般而言,退出码对应的
return语句还没执行到就已经崩溃了!


7. perror函数以及变量errno

errno是C语言中的一个全局变量

它里面存储的是最近的一个错误码
比如使用fopen函数打开文件时,
如果打开失败了,不仅仅文件指针fp
会被赋值为NULL,此时错误码errno
也会被系统自动赋值!

perror是C语言中常用的关于错误的函数

perror函数总是和errno搭配在一起
此函数会输出errno错误码对应的错误
信息,并且,perror的参数代表是哪个地方
有问题,是用户自己决定的!比如我们通常
这样来写一段代码:

FILE* fp = fopen("csdn.txt","r");
if(fp==NULL)
{
  perror("fopen");
  exit(1);
}

注意:打印出来的信息中,前面的fopen:
是用户输入的信息,后面的语句是errno
错误码对应的错误信息


8. 总结

进程终止话题是进程控制中最简单
的话题,学好进程终止可以提高我们
代码的可阅读性,可以把错误信息
展现的更加明了!

在本篇文章中出现的缓冲区概念只用于
区别exit和_exit的作用,更多关于缓冲区的
内容,我们将在Linux的基础IO中讲解!


🔎 下期预告:Linux进程等待 🔍


相关文章
|
17天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
43 1
|
5天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
47 13
|
12天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
20天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
138 4
linux进程管理万字详解!!!
|
25天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
78 8
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
72 1
|
1月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
71 4