Linux signal()函数
这是在网易云课堂学习Linux下的signal()函数的笔记,课程链接:https://study.163.com/course/courseLearn.htm?courseId=1002913011&share=1&shareId=1024164580#/learn/video?lessonId=1003302216&courseId=1002913011
1. 函数原型
可通过man signal命令查看。

signum:要登记的信号值
handler:信号处理函数指针,可以是自定义的信号处理函数,或者SIG_IGN(忽略信号),或者SIG_DFL(采用系统默认方式处理信号)。
系统中有很多信号,每种信号都有一个宏定义,在/usr/include/bits/signum.h 文件中进行的定义。或者使用kill -l可以查看有哪些信号。

我们平时用的命令“kill -9 进程号”就是向系统发送了一个SIGKILL信号。
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
2. 信号的处理
进程可以通过三种方式来响应和处理一个信号:
1)忽略信号
SIGKILL和SIGSTOP永远不能被忽略;
忽略硬件异常;
进程启动时SIGUSR1和SIGUSR2两个信号被忽略。
2)执行默认操作
每个信号有默认动作,大部分信号默认动作是终止信号。
3)捕获信号
告诉内核出现信号时调用自己的处理函数;
SIGKILL和SIGSTOP不能被捕获。
3. 测试代码
下面的测试代码是对两种信号使用自己定义的信号处理函数进行处理,这两种信号分别是:
#define SIGINT 2 /* Interrupt (ANSI). 按ctrl+c产生*/
#define SIGTSTP 20 /* Keyboard stop (POSIX). 按ctrl+z产生*/
代码如下:
1 #include <signal.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 // 定义信号处理函数
6 // signo:捕获到的信号
7 void sig_handler(int signo)
8 {
9 printf("%d: %d occured\n", getpid(), signo);
10 }
11
12
13 int main(void)
14 {
15 // 向内核登记信号处理函数及信号值
16 if (signal(SIGTSTP, sig_handler) == SIG_ERR) {
17 perror("signal sigtstp error");
18 }
19 if (signal(SIGINT, sig_handler) == SIG_ERR) {
20 perror("signal sigint error");
21 }
22
23 int i = 0;
24 while (i < 30) {
25 printf("%d, %d\n", getpid(), i++);
26 sleep(1);
27 }
28
29 return 0;
30 }
测试结果:

4. 其它测试1
我们将signal()相关的代码注释掉,来进行测试:
#include <signal.h>
#include <stdlib.h>
#include <stdio.h> // 定义信号处理函数
// signo:捕获到的信号
void sig_handler(int signo)
{
printf("%d: %d occured\n", getpid(), signo);
} int main(void)
{
// 向内核登记信号处理函数及信号值
// if (signal(SIGTSTP, sig_handler) == SIG_ERR) {
// perror("signal sigtstp error");
// }
// if (signal(SIGINT, sig_handler) == SIG_ERR) {
// perror("signal sigint error");
// } int i = 0;
while (i < 30) {
printf("%d, %d\n", getpid(), i++);
sleep(1);
} return 0;
}
测试结果:

可以看出,系统对SIGINT信号的默认处理方式是终止程序的运行,对SIGTSTP信号的默认处理方式是暂停程序的运行。

我们可以使用SIGCONT信号来让程序继续运行:kill -SIGCONT 3131。
5. 其它测试2
使用忽略的方式SIG_IGN来处理信号:
1 #include <signal.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 // 定义信号处理函数
6 // signo:捕获到的信号
7 void sig_handler(int signo)
8 {
9 printf("%d: %d occured\n", getpid(), signo);
10 }
11
12
13 int main(void)
14 {
15 // 向内核登记信号处理函数及信号值
16 if (signal(SIGTSTP, sig_handler) == SIG_ERR) {
17 perror("signal sigtstp error");
18 }
19 if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
20 perror("signal sigint error");
21 }
22
23 int i = 0;
24 while (i < 30) {
25 printf("%d, %d\n", getpid(), i++);
26 sleep(1);
27 }
28
29 return 0;
30 }
测试结果:

可以看出,使用忽略方式并没有捕获到信号SIGINT,SIG_IGN方式把SIGINT忽略掉了。
Linux signal()函数的更多相关文章
- linux signal函数遇到的问题
1.关于signal函数的定义 signal最开始的原型是这: void (*signal(int signo, void (*func)(int)))(int);看过下面两行,了解到上面这一行是这个 ...
- [linux]signal函数不起作用
#include "apue.h" #include <sys/wait.h> static void sig_int(int); /* our signal-catc ...
- Signal ()函数详细介绍 Linux函数
http://blog.csdn.net/ta893115871/article/details/7475095 Signal ()函数详细介绍 Linux函数 signal()函数理解 在<s ...
- Signal ()函数详细介绍 Linux函数(转)
Signal ()函数详细介绍 Linux函数 收藏人:紫火神兵 2012-09-27 | 阅:5659 转:22 | 来源 | 分享 signa ...
- 三十、Linux 进程与信号——信号的概念及 signal 函数
30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...
- Linux下利用signal函数处理ctrl+c等信号
前言 linux下能够通过信号机制来实现程序的软中断,是一个很实用的编程方法. 我们平时在程序执行的时候按下ctrl-c.ctrl-z或者kill一个进程的时候事实上都等效于向这个进程发送了一个特定信 ...
- Linux 信号(二)—— signal 函数
弗洛伊德认为:要解决这些苦恼,当事人就要通过回忆并理解自己早期的童年经历,来获得对潜意识冲突的顿悟.弗洛伊德的疗法被称为“精神分析” (psychoanalysis),在 20 世纪的很长一段时间被心 ...
- Linux 信号详解一(signal函数)
信号列表 SIGABRT 进程停止运行 SIGALRM 警告钟 SIGFPE 算述运算例外 SIGHUP 系统挂断 SIGILL 非法指令 SIGINT 终端中断 SIGKILL 停止进程(此信号不能 ...
- signal()函数
转自:http://blog.csdn.net/sddzycnqjn/article/details/7285760 1. 信号概念 信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件) ...
- signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数
信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...
随机推荐
- python数据库迁移
实际操作命令 1,python 文件.py db init 2,python xx.py db migrate -m '版本描述' 3,python xx.py db upgrade 4,python ...
- 力扣619(MySQL)-只出现一次的最大数字(简单)
题目: MyNumbers 表: 单一数字 是在 MyNumbers 表中只出现一次的数字. 请你编写一个 SQL 查询来报告最大的 单一数字 .如果不存在 单一数字 ,查询需报告 null . 查询 ...
- 暑期集训 Day11 —— 模拟赛复盘
${\color{Green} \mathrm{Problem\ 1 :Subarray }} $ 签到失败... 直接二进制分组,找出所有二进制位=0 的方法. 死因: 二进制分组没想出来... $ ...
- 更便捷:阿里云DCDN离线日志转存全新升级
简介: 1月6日,阿里云CDN年度产品升级发布会中,阿里云CDN产品专家邓建伟宣布DCDN离线日志转存全新升级,并对离线日志转存方案的价值.应用及使用进行了详细解读. 在日常CDN加速服务过程中会产生 ...
- 如何合理使用 CPU 管理策略,提升容器性能?
简介:CPU Burst.拓扑感知调度是阿里云容器服务 ACK 提升应用性能的两大利器,它们解决了不同场景下的 CPU 资源管理,可以共同使用.点击下文,查看详情! 作者:张佐玮(佑祎) 前言 在云 ...
- Linux系统诊断-内存基础
简介: Linux系统诊断-内存基础 1. 背景 谈及linux内存,很多时候,我们会关注free,top等基础命令.当系统遇到异常情况时,内存问题的根因追溯,现场诊断时,缺乏深层次的debug能力. ...
- N个技巧,编写更高效 Dockerfile|云效工程师指北
简介:云原生时代下软件的构建和部署离不开容器技术.提到容器,几乎大家下意识都会联想到 Docker .而 Docker 中有两个非常重要的概念,一个是Image(镜像),一个是Container(容器 ...
- UNO 的 SamplesApp.Skia.Gtk 丢失字体文件抛出空异常
在运行 UNO 的 SamplesApp.Skia.Gtk 例子程序时,如果没有拷贝字体文件夹,导致字体丢失,将会在运行的时候抛出 NullReferenceException 空异常 抛出的异常堆栈 ...
- 手把手教你如何构建 WPF 官方开源框架源代码
从去年微软就将 WPF 开源了,差不多现在所有 WPF 的源代码都开源了.在学习框架的时候,我会做一些改动,期望能构建一个自己的版本进行测试.但是作为一个特别大的框架,想要构建跑起来可不是直接在 Vi ...
- 🎉 Socket.D v2.4.12 发布(新增 python 实现)
Socket.D 协议? Socket.D 是一个网络应用协议.在微服务.移动应用.物联网等场景,可替代 http.websocket 等.协议详情参考<官网介绍>. 支持: tcp, u ...