这是在网易云课堂学习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. redis+lua脚本实现接口限流

    写在前面 在多线程的情况下对一个接口进行访问,如果访问次数过大,且没有缓存存在的情况下大量的请求打到数据库可能会存在数据库宕机,从而造成服务的不可用性.往往我们需要对其进行限流操作用来保证服务的高可用 ...

  2. [Violation] 'click' handler took 429ms

    问题 violation 意思为侵权,违背,违反,也就是说明click函数执行违反了某些规则 原因测试 当click事件中执行的程序耗时过长,超过160ms左右的时候就会显示该信息,测试最低155ms ...

  3. 【笔记】connect by中的nocycle

    connect by主要用于父子,祖孙,上下级等层级关系的查询 常用的是prior,nocycle prior: 查询父行的限定符,格式: prior column1 = column2 or col ...

  4. 蚂蚁一面:GC垃圾回收时,内存分配和回收策略有哪些?

    文章首发于公众号:腐烂的橘子 蚂蚁面试主要为电话面试,期间也会要求使用编辑器手写算法题.作为一线互联网大厂,Java 基础知识是必备的,其中垃圾回收也是面试过程中的重中之重. Java 内存的自动管理 ...

  5. Helm Chart 多环境、多集群交付实践,透视资源拓扑和差异

    简介: 在本文中,我们将介绍如何通过 KubeVela解决多集群环境下 Helm Chart 的部署问题.如果你手里没有多集群也不要紧,我们将介绍一种仅依赖于 Docker 或者 Linux 系统的轻 ...

  6. 迁移 Express 到函数计算

    首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计 ...

  7. 先行一步,7大技术创新和突破,阿里云把 Serverless 领域的这些难题都给解了

    ​简介: 函数计算 FC 首创 GPU 实例.业内首发实例级别可观测和调试.率先提供端云联调和多环境部署能力.GB 级别镜像启动时间优化至秒级.VPC 网络建连优化至200ms,Serverless ...

  8. dotnet C# 通过 Vortice 将 ID2D1CommandList 作为特效的输入源

    使用 Direct2D 过程中将可以使用到 Direct2D 强大的特效功能,比如给某些界面绘制内容添加特效支持.本文将告诉大家如何通过 Vortice 将 ID2D1CommandList 作为特效 ...

  9. SpringCloud + Seata1.5.0(使用docker安装配置Seata;数据存储mysql、配置中心与注册中心nacos)

    1.seata介绍 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分 ...

  10. SqlServer2008R2 在开始菜单中找不到配置管理器

    直接找到C:\Windows\SysWOW64\SQLServerManager10.msc,打开即可.