| |
|
开发:
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。 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; } |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |