[linux]进程控制——进程终止

一、main函数的返回值

我们在编写C语言的程序时,通常会这样写:

cpp 复制代码
int main()
{
    return 0;
}

那么我们为什么要返回(return)0 呢?

其实,main函数也是一个函数,它也会被调用,所以谁调用main函数,这个返回值就会返回给谁。

我们写一个test.c来观察:

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


int main()
{
  //code


  return 3;
}

执行以上程序,我们可以看到return返回值写的是3。

我们可以通过 echo $? 查看进程退出码:

  • main函数的 返回值,就叫做进程的退出码。
  • 0 -> sucess (0表示成功)
  • !0 -> failed (!0表示失败);此时我们就可以用不同的数字表示不同的原因

main函数的退出码是可以被父进程获取的,用来判断子进程的运行结果。

注:

纯数字虽然能表明出原因,但是不便于人类的阅读,所以我们将 exit code -> exit code string(可以用内置的,也可以自定义)

例:打印Linux中的错误码信息(根据运行结果可以看出有133个)

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


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

  return 3;
}

我们运行的mybin文件就是bash的子进程。子进程退出时,退出码会被它的父进程自动获得。

echo $? 中,?中保存的是最近一个子进程执行完毕时的退出码。

例:

错误码是127

错误码是1

错误码与退出码

  • 错误码通常是衡量一个库函数或者是一个系统调用、一个函数的调用情况
  • 退出码通常是一个进程退出的时候,它的退出结果

相同的是,当失败的时候,用来衡量函数、进程出错时的出错详细原因。

二、进程终止

1、进程退出场景

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

异常:

进程出现异常,本质是进程收到了对应的信号,自己终止了。

例:

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


int main()
{
  char* p = NULL;
  *p = 1;

  return 0;
  
}

运行后:

出现异常后,操作系统会根据发送的信号将该进程杀死。

Linux中:

那么,我们可以通过发送信号来终止一个进程 :

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

int main()
{
  while(1)
  {
    printf("进程: %d\n", getpid());
    sleep(1);
  }
  
  
  return 0;
}

程序运行:

此时,我们可以通过kill -11 27747 杀死该进程 (以 -11 为例,也可以是其它信号):

因此,一个进程是否出异常,我们只需看有没有收到信号即可。

2、exit(进程的退出码)

(任何时间,任何地点,exit,随时结束!)

任意地点调用exit,都表示进程直接退出,不进行后续执行。

exit:

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

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

  3. 调用_exit

例:

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

int main()
{
  printf("test\n");

  exit(13);
  
  return 0;
}

3、_exit和exit

  • exit是库函数,_exit是系统调用
  • exit终止进程的时候,会自动刷新缓冲区;_exit终止进程的时候,不会自动刷新缓冲区

注:缓冲区不在操作系统内部。

相关推荐
readhere6 小时前
从ZYNQ7000开发板,学会启动嵌入式Linux系统——入门学习:EBAZ4205篇目录
linux·启动·嵌入式linux·zynq7000·ebaz4205
打工仔折腾 AI7 小时前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
‎ദ്ദിᵔ.˛.ᵔ₎8 小时前
关于Linux 线程局部存储的认识
linux·运维
小小de风呀10 小时前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习
lhbweilai11 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
晚风吹北巷11 小时前
Linux复习篇(自用)
linux·运维·服务器·1024程序员节
艾络迅Acceleronix11 小时前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节
Zwawa12 小时前
一只按键不只“按下”:短按、长按和连按如何共存
c语言·单片机·嵌入式
by2099912 小时前
Linux 压缩传输、进程查看与权限管理
linux·经验分享·1024程序员节