这是在网易云课堂学习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()函数的更多相关文章

  1. linux signal函数遇到的问题

    1.关于signal函数的定义 signal最开始的原型是这: void (*signal(int signo, void (*func)(int)))(int);看过下面两行,了解到上面这一行是这个 ...

  2. [linux]signal函数不起作用

    #include "apue.h" #include <sys/wait.h> static void sig_int(int); /* our signal-catc ...

  3. Signal ()函数详细介绍 Linux函数

    http://blog.csdn.net/ta893115871/article/details/7475095 Signal ()函数详细介绍 Linux函数 signal()函数理解 在<s ...

  4. Signal ()函数详细介绍 Linux函数(转)

    Signal ()函数详细介绍 Linux函数 收藏人:紫火神兵     2012-09-27 | 阅:5659  转:22    |   来源   |  分享               signa ...

  5. 三十、Linux 进程与信号——信号的概念及 signal 函数

    30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...

  6. Linux下利用signal函数处理ctrl+c等信号

    前言 linux下能够通过信号机制来实现程序的软中断,是一个很实用的编程方法. 我们平时在程序执行的时候按下ctrl-c.ctrl-z或者kill一个进程的时候事实上都等效于向这个进程发送了一个特定信 ...

  7. Linux 信号(二)—— signal 函数

    弗洛伊德认为:要解决这些苦恼,当事人就要通过回忆并理解自己早期的童年经历,来获得对潜意识冲突的顿悟.弗洛伊德的疗法被称为“精神分析” (psychoanalysis),在 20 世纪的很长一段时间被心 ...

  8. Linux 信号详解一(signal函数)

    信号列表 SIGABRT 进程停止运行 SIGALRM 警告钟 SIGFPE 算述运算例外 SIGHUP 系统挂断 SIGILL 非法指令 SIGINT 终端中断 SIGKILL 停止进程(此信号不能 ...

  9. signal()函数

    转自:http://blog.csdn.net/sddzycnqjn/article/details/7285760 1. 信号概念 信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件) ...

  10. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

随机推荐

  1. 【SSH通道数据库连接池】连接远程linix服务器上面的mysql

    首先,我用的是阿里的druid数据库连接池,其次,需要第三方jar包,maven坐标如下: <dependency> <groupId>com.jcraft</group ...

  2. vscode使用npm安装依赖报错

    1.报错信息 npm ERR! code EPERM npm ERR! syscall open npm ERR! path C:\Node\node_cache_cacache\index-v5\4 ...

  3. 2FA(双因素身份验证)之手机令牌(TOTP)逻辑

    2FA(双因素身份验证)之手机令牌(TOTP)逻辑 纯猜测,没试过,有空试 分为移动端.客户端以及网页端 Steam那种属于APP是网页,客户端是网页,网页端也是网页,挺抽象的 关键点: 时间一致(时 ...

  4. 力扣481(java&python)-神奇字符串(中等)

    题目: 神奇字符串 s 仅由 '1' 和 '2' 组成,并需要遵守下面的规则: 神奇字符串 s 的神奇之处在于,串联字符串中 '1' 和 '2' 的连续出现次数可以生成该字符串.s 的前几个元素是 s ...

  5. 基于IoT全链路实时质量-魔洛哥

    简介: 通过基于IoT的全链路实时质量,业务使用狄仁杰进行全链路埋点后,可一键接入魔洛哥平台,实现终端问题的实时感知和链路分析,以及智能终端系统业务场景的全链路实时质量.整体方案接入成本低(分钟级别接 ...

  6. 疫情带火了这款APP:2600个学生一天点赞70万次

      这几天,全国中小学生经历了"过山车"一样的心情. 因为疫情的不断蔓延,1月27日,教育部下发通知,2020年春季学期延期开学. 随后,教育部又提出"利用网络平台,停课 ...

  7. Sentinel 1.7.2 发布,完善开源生态及扩展性

    多样化的适配模块 到目前为止,Sentinel 已覆盖微服务.API Gateway 和 Service Mesh 三大板块的核心生态,同时多语言已推出 Java.C++.Go 三种语言的原生实现. ...

  8. HTML中元素分类与对应的CSS样式特点

    元素就是标签,布局中常用的有三种标签,块元素.内联元素.内联块元素,了解这三种元素的特性,才能熟练的进行页面布局. 块元素 块元素,也可以称为行元素,布局中常用的标签如:div.p.ul.li.h1~ ...

  9. [Go] Go Module 私有依赖包的管理

    一些自研开发的第三方包,特别是一些业务依赖包,是不允许公开下载的(私有库),并且版本库也可能不支持HTTPS协议, 因此无法使用 go get 或者 go.mod 进行下载和管理,可以通过 GOPRI ...

  10. 实践探讨Python如何进行异常处理与日志记录

    本文分享自华为云社区<Python异常处理与日志记录构建稳健可靠的应用>,作者:柠檬味拥抱. 异常处理和日志记录是编写可靠且易于维护的软件应用程序中至关重要的组成部分.Python提供了强 ...