IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux系统下程序异常如何优雅的退出 -> 正文阅读

[系统运维]Linux系统下程序异常如何优雅的退出

????????当我们想强制结束一个程序的时候,我们通常会给它发送一个信号然后该进程捕捉到信号,再然后该进程执行一定操作最终被终止。信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动。通常信号是由一个错误产生的。但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程。

????????一个信号的产生叫生成,接收到一个信号叫捕获,生成信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort(),最常用的是kill;捕获信号的主要函数有:signal(),sigprocmask()?,sigpending(),sigsuspend(),?sigemptyset(),最常用的是signal。下面重点讲一下kill和signal的使用。

1.信号的生成kill

在Linux系统下想结束某个进程时,用的最多的指令就是kill或者killall,这就是常用的信号生成方式,在程序运行时ctrl+c中断进程,会产生信号SIGINT。在Linux系统对应kill命令也有kill函数,c语言引入头文件sys/types.h和signal.h之后就可以使用。kill 送出一个特定的信号 (signal) 给行程 id 为 pid 的行程根据该信号而做特定的动作,若没有指定,预设是送出终止 (SIGTERM) 的信号,例如kill -9 pid就是强制杀死进程号为pid的进程。在这里有人就会问为什么要用-9呢,-9只是kill发送信号的一个编号,可以输入kill –l把kill所有可用的信号名称列出来。

kill -9 意思是把SIGKILL信号发送给进程号为pid的进程。

其中前面31个信号为不可靠信号(非实时的,可能会出现信号的丢失),后面的信号为可靠信号(实时的real_time,对信号排队,不会丢失)。

1) SIGHUP (挂起) 当运行进程的用户注销时通知该进程,使进程终止

2) SIGINT (中断) 当用户按下时,通知前台进程组终止进程

3) SIGQUIT (退出) 用户按下或时通知进程,使进程终止

4) SIGILL (非法指令) 执行了非法指令,如可执行文件本身出现错误、试图执行数据段、堆栈溢出

5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用

6) SIGABRT (异常中止) 调用abort函数生成的信号

7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.

8) SIGFPE (算术异常) 发生致命算术运算错误,包括浮点运算错误、溢出及除数为0.

9) SIGKILL (确认杀死) 当用户通过kill -9命令向进程发送信号时,可靠的终止进程

10) SIGUSR1 用户使用

11) SIGSEGV (段越界) 当进程尝试访问不属于自己的内存空间导致内存错误时,终止进程

12) SIGUSR2 用户使用

13) SIGPIPE 写至无读进程的管道, 或者Socket通信SOCT_STREAM的读进程已经终止,而再写入。

14) SIGALRM (超时) alarm函数使用该信号,时钟定时器超时响应

15) SIGTERM (软中断) 使用不带参数的kill命令时终止进程

17) SIGCHLD (子进程结束) 当子进程终止时通知父进程

18) SIGCONT (暂停进程继续) 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞.

19) SIGSTOP (停止) 作业控制信号,暂停停止(stopped)进程的执行. 本信号不能被阻塞, 处理或忽略.

20) SIGTSTP (暂停/停止) 交互式停止信号, Ctrl-Z 发出这个信号

21) SIGTTIN 当后台作业要从用户终端读数据时, 终端驱动程序产生SIGTTIN信号

22) SIGTTOU 当后台作业要往用户终端写数据时, 终端驱动程序产生SIGTTOU信号

23) SIGURG 有"紧急"数据或网络上带外数据到达socket时产生.

24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。

25) SIGXFSZ 当进程企图扩大文件以至于超过文件大小资源限制。

26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.

27) SIGPROF (梗概时间超时) setitimer(2)函数设置的梗概统计间隔计时器(profiling interval timer)

28) SIGWINCH 窗口大小改变时发出.

29) SIGIO(异步I/O) 文件描述符准备就绪, 可以开始进行输入/输出操作.

30) SIGPWR 电源失效/重启动

31) SIGSYS 非法的系统调用。

程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP。
不能恢复至默认动作的信号有:SIGILL,SIGTRAP。
默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM。
默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU。
默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH。

2.信号的捕获signal

signal的函数原型是:

typedef void (*sig_t)( int );

sig_t signal(int signum,sig_t handler);

第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。

第二个参数handler描述了与信号关联的动作,它可以取以下三种值:

(1)一个无返回值的函数地址

此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为signum的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义:

void func(int sig);

(2)SIG_IGN

这个符号表示忽略该信号,执行了相应的signal()调用后,进程会忽略类型为sig的信号。

(3)SIG_DFL

这个符号表示恢复系统对信号的默认处理。

最常用的捕获signal场景是当signal到来时,程序运行某函数,函数由你自己指定,此时函数一般是做一些资源的释放,比如socket关闭,内存释放,文件关闭,有人会说了我不释放那些资源也可以退出程序,你说的没错,你不做任何处理一样可以退出程序,但是有时会影响其他共享或者交互进程,比如作为服务端异常退出时不主动关闭socket,可能会导致客户端不知道断开连接,导致某些数据丢失或者逻辑异常,所以在程序正常和异常退出时最好都做到优雅,这里除了SIGKILL,SIGSTOP除外,因为这些信号无法捕获想优雅退出不给机会。

代码示例:

#include?<stdio.h>

#include?<signal.h>

void?server_uninit()

{

//释放所有资源

printf("close all socket and file\n");

}

void?func1()

{

????????printf("SIGINT \n");

????????server_uninit();

????????printf("可以优雅的退出程序了 \n");

????????exit(0);

}

void?func2()

{

????????printf("SIGTERM \n");

????????server_uninit();

????????printf("可以优雅的退出程序了 \n");

????????exit(0);

}

void?func3()

{

printf("SIGSEGV \n");

server_uninit();

printf("可以优雅的退出程序了 \n");

exit(0);

}

void?func0()

{

printf("SIGKILL \n");

server_uninit();

printf("可以优雅的退出程序了 \n");

exit(0);

}

int?main()

{

????????signal?(SIGINT, func1);

????????signal(SIGKILL, func0);

????????signal(SIGSEGV, func3);

????????signal(SIGTERM, func2);

????????int?i = 0;

????????while(1)

????????{

????????????????printf("i %d\n",i++);

????????????????sleep(2);

?????????}????????

????????return?0;

}

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 12:01:58  更:2022-05-05 12:03:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:42:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码