12.linux中的信号
2016-09-02 15:37
134 查看
12.1.什么是信号
(1)信号是通信内容受限(int型数字)的1种异步通信机制;信号是当前进程对外通信的1种手段;信号的目的用来通信的;信号是异步的(类似硬件中断);信号本质上是操作系统事先定义好的int型数字编号。
(2)信号由谁发出;用户在终端按下按键(譬如用户按下Ctrl+c按键终止程序运行);硬件异常后由操作系统内核发出信号;用户使用kill命令向其它进程发出信号;某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向1个读端已经关闭的管道write时会产生SIGPIPE信号。
(3)信号由谁处理并如何处理;忽略信号(收到信号直接丢弃);捕获信号(信号绑定了某个函数);默认处理(当前进程收到该信号后执行信号默认操作,一般是忽略或终止进程)。
12.2.常见信号介绍
(1)SIGINT(2-Ctrl+C时OS送给前台进程组中每个进程);SIGABRT(6-调用abort函数,进程异常终止);SIGPOLL/SIGIO(8-指示1个异步IO事件,在高级IO中提及);SIGKILL(9-杀死进程的终极办法,该信号无法被忽略);SIGSEGV(11-无效存储访问时OS发出该信号,提示段错误信息)。
(2)SIGPIPE(13-涉及管道和socket编程);SIGALARM(14-涉及alarm函数的实现);SIGTERM(15-kill命令发送的OS默认终止信号);SIGCHLD(17-子进程终止或停止时OS向其父进程发此信号)。SIGUSR1
(3)SIGUSR1(10-用户自定义信号,作用和意义由应用自己定义);SIGUSR2(12-用户自定义信号,作用和意义由应用自己定义)。
(4)信号定位在/usr/include/signal.h和/usr/include/i386-linux-gnu/bits/signum.h这两个头文件中。
12.3.进程对信号的处理
(1)默认处理+忽略处理+捕获处理;signal函数绑定某个捕获函数后,当信号发生后会自动执行绑定的捕获函数,并且把信号编号作为传参传给捕获函数;signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数;signal函数的优点-简单好用,捕获信号常用;缺点-无法简单直接得知之前设置的对信号的处理方法。
(2)sigaction函数比signal更具有可移植性,其使用方法的关键是2个sigaction指针;sigaction可以1次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数必须在设置新的捕获函数的同时才获取旧的捕获函数。
12.4.alarm和pause函数
(1)alarm函数,内核以API形式提供的闹钟;内核在1个进程中只维持1个alarm闹钟,在首次调用alarm后会返回0,在第2次调用alarm后返回上次闹钟还剩下的秒数并重新注册alarm闹钟。
(2)pause函数,pause函数的作用就是让当前进程暂停运行,交出CPU给其它进程去执行,当前进程进入pause状态后当前进程会表现为卡住/阻塞住,退出pause状态当前进程需要被信号唤醒。
(1)信号是通信内容受限(int型数字)的1种异步通信机制;信号是当前进程对外通信的1种手段;信号的目的用来通信的;信号是异步的(类似硬件中断);信号本质上是操作系统事先定义好的int型数字编号。
(2)信号由谁发出;用户在终端按下按键(譬如用户按下Ctrl+c按键终止程序运行);硬件异常后由操作系统内核发出信号;用户使用kill命令向其它进程发出信号;某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向1个读端已经关闭的管道write时会产生SIGPIPE信号。
(3)信号由谁处理并如何处理;忽略信号(收到信号直接丢弃);捕获信号(信号绑定了某个函数);默认处理(当前进程收到该信号后执行信号默认操作,一般是忽略或终止进程)。
12.2.常见信号介绍
(1)SIGINT(2-Ctrl+C时OS送给前台进程组中每个进程);SIGABRT(6-调用abort函数,进程异常终止);SIGPOLL/SIGIO(8-指示1个异步IO事件,在高级IO中提及);SIGKILL(9-杀死进程的终极办法,该信号无法被忽略);SIGSEGV(11-无效存储访问时OS发出该信号,提示段错误信息)。
(2)SIGPIPE(13-涉及管道和socket编程);SIGALARM(14-涉及alarm函数的实现);SIGTERM(15-kill命令发送的OS默认终止信号);SIGCHLD(17-子进程终止或停止时OS向其父进程发此信号)。SIGUSR1
(3)SIGUSR1(10-用户自定义信号,作用和意义由应用自己定义);SIGUSR2(12-用户自定义信号,作用和意义由应用自己定义)。
(4)信号定位在/usr/include/signal.h和/usr/include/i386-linux-gnu/bits/signum.h这两个头文件中。
12.3.进程对信号的处理
(1)默认处理+忽略处理+捕获处理;signal函数绑定某个捕获函数后,当信号发生后会自动执行绑定的捕获函数,并且把信号编号作为传参传给捕获函数;signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数;signal函数的优点-简单好用,捕获信号常用;缺点-无法简单直接得知之前设置的对信号的处理方法。
(2)sigaction函数比signal更具有可移植性,其使用方法的关键是2个sigaction指针;sigaction可以1次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数必须在设置新的捕获函数的同时才获取旧的捕获函数。
12.4.alarm和pause函数
(1)alarm函数,内核以API形式提供的闹钟;内核在1个进程中只维持1个alarm闹钟,在首次调用alarm后会返回0,在第2次调用alarm后返回上次闹钟还剩下的秒数并重新注册alarm闹钟。
(2)pause函数,pause函数的作用就是让当前进程暂停运行,交出CPU给其它进程去执行,当前进程进入pause状态后当前进程会表现为卡住/阻塞住,退出pause状态当前进程需要被信号唤醒。
12.signal /* * 公司:XXXX * 作者:Rston * 博客:http://blog.csdn.net/rston * GitHub:https://github.com/rston * 项目:linux中的信号 * 功能:演示signal函数的简单使用。 */ #include <stdio.h> #include <signal.h> #include <stdlib.h> typedef void (*sighandler_t)(int); // ctrl+c信号捕捉函数 void signal_func(int sig) { printf("I catch ctrl + c.\n"); } int main(int argc, char **argv) { #if 1 // 指定信号SIGINT为具体的signal_func处理函数 sighandler_t ret = ((sighandler_t) -2); ret = signal(SIGINT, signal_func); if (SIG_ERR == ret) { perror("signal error"); exit(-1); } #endif #if 0 // 指定信号SIGINT为默认处理 signal(SIGINT, SIG_DFL); #endif #if 0 // 指定信号SIGINT为忽略处理 signal(SIGINT, SIG_IGN); #endif printf("before while(1).\n"); while(1); printf("after while(1).\n"); return 0; }
12.sigaction_alarm_pause /* * 公司:XXXX * 作者:Rston * 博客:http://blog.csdn.net/rston * GitHub:https://github.com/rston * 项目:linux中的信号 * 功能:演示sigaction和alarm和pause函数的简单使用。 */ #include <stdio.h> #include <signal.h> #include <unistd.h> void mysleep(unsigned int seconds); #if 1 void signal_func(int sig) { } #endif #if 0 void signal_func(int sig) { printf("alarm happened.\n"); } #endif int main(int argc, char **argv) { #if 0 int ret = -1; struct sigaction act = {0}; act.sa_handler = signal_func; ret = sigaction(SIGALRM, &act, NULL); ret = alarm(5); printf("1st, ret = %d.\n", ret); // 1st, ret = 0. sleep(3); ret = alarm(5); printf("2st, ret = %d.\n", ret); // 2st, ret = 2. sleep(1); ret = alarm(5); printf("3st, ret = %d.\n", ret); // 3st, ret = 4. #if 0 while (1); #endif #if 1 pause(); #endif #endif #if 1 // 使用alarm和pause来模拟sleep printf("before mysleep.\n"); mysleep(3); printf("after mysleep.\n"); #endif return 0; } #if 0 void mysleep(unsigned int seconds) { struct sigaction act = {0}; act.sa_handler = signal_func; sigaction(SIGALRM, &act, NULL); alarm(seconds); pause(); } #endif
相关文章推荐
- 解读QT信号与槽机制里 QMetaObject::connectSlotsByName(QObject *o)的源码
- Filters.h各种信号恢复滤波器头文件
- 信号基本概念
- Qt深入理解信号与槽
- 信号和槽使用时各种函数的实际调用顺序
- RAC基础学习一:信号和订阅者模式
- SIGHUP信号与控制终端
- unix环境编程·信号特性
- C 轻量级 信号与槽
- sleep与信号
- 进程-IPC 信号和信号量 (二)
- Linux中 信号signal
- QT 的信号与槽机制介绍
- Linux中信号处理的两种方法
- 基于信号处理的在线云评测+社区系统( 10)
- Qt的动态信号与槽机制
- Sicily 1214. 信号分析
- linux中信号的产生 阻塞与捕捉
- Linux信号及信号处理学习总结
- Android显示wifi信号强度以及周边信号的代码