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)操作函数
信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...
随机推荐
- Go 单元测试之mock接口测试
目录 一.gomock 工具介绍 二.安装 三.使用 3.1 指定三个参数 3.2 使用命令为接口生成 mock 实现 3.3 使用make 命令封装处理mock 四.接口单元测试步骤 三.小黄书Se ...
- easyx的使用,鼠标交互(3.0)
本文从B站学习,借鉴: 学习视频地址:鼠标操作(旧版)_哔哩哔哩_bilibili
- Oracle的主键id自增
Oracle的主键id自增 可以直接用序列加触发器的方式实现 首先表里面要有个主键,没有的话用语句或者在编译器中加一下,都可以 然后创建一个序列,一般来说最常用的有这几个参数 CREATE SEQUE ...
- 力扣258(java)-各位相加(简单)
题目: 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数.返回这个结果. 示例 1: 输入: num = 38输出: 2 解释: 各位相加的过程为:38 --> 3 + 8 ...
- 科普达人丨漫画图解SGX加密计算黑科技
介: 运行态的数据也可以被加密,实现数据可用不可见. 01 从一场朋友圈的"赛富"说起 最近,小明买基金赚了不少钱,开始膨胀了,开始在朋友圈里晒豪车.晒爱马仕.小红表示不服,&qu ...
- 工业视觉智能实战经验之IVI算法框架2.0
简介: 工业视觉智能团队在交付了多个工业视觉智能质检项目后,发现了工业视觉智能的共性问题和解法,打造了工业视觉智能平台,通过平台的方式积累和提升工业视觉的通用能力.在平台建设上最核心的能力是算法能力 ...
- vue实现左右两列竖直分别滑动,且双向关联的选项卡(二)
查了诸如vant,mint组件上并没有找到期望的这种效果(cube组件上有,但项目中实在不想再引入一个第三方的组件库了),但实际上在移动端app开发中很常见的一个效果.于是按照自己的思路将这个效果做了 ...
- 六:大数据架构 - Flink + AI
Flink 在AI 中的价值其实和大数据Lambda架构中流批统一这两个概念有关系,Flink为大数据实时化带来的价值也将同样使AI受益 大数据的发展过程 从Google奠基性的"三架马车& ...
- Winform项目中纯代码创建WCF服务
接口: [ServiceContract(CallbackContract = typeof(IViewCallback), SessionMode = SessionMode.Required)] ...
- 密钥存储在过时的 trusted.gpg 密钥环中(/etc/apt/trusted.gpg)
密钥存储在过时的 trusted.gpg 密钥环中(/etc/apt/trusted.gpg) 问题: 解决: cd /etc/opt sudo cp trusted.gpg trusted.gpg. ...