C++ Signal(信号)
- 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称软中断。从它的命名可以看出,它的实质和使用很像中断,所有,信号可以说是进程控制的一部分。
- 信号
signal
处理是Linux
程序的一个特色,用信号处理来模拟操作系统的中断功能。#include <csignal>
或#include <signal.h>
是处理信号的C-library
。
- 1. 什么是信号
- 2. 函数 signal
- 2.1 默认处理-SIG_DFL
- 2.2 忽略信号-SIG_IGN
- 2.3 自定义函数
- 3. 函数 raise
- 4. 其他信号
1. 什么是信号
#include <csignal>
或#include <signal.h>
是处理信号的C-library
。该库包含signal
与raise
两个功能函数。
I. 函数signal
用于捕获信号,可指定信号处理的方式。
II. 函数raise
产生一个信号,并向当前正在执行的程序发送该信号。
- 信号
signal
可以理解为由操作系统传给程序(进程)的事件,只是用来通知程序发生了什么事件,并不会传递给该进程任何数据. - 信号是一种中断,因为它可以改变程序的流程。当信号传递给进程时,进程将停下其正在执行的操作,并去处理或忽略该信号
异步事件
。
异步事件
- 查看信号的方式是一种处理异步
事件的机制。
▶ 当程序
通过 signal 函数捕获信号后,若signal
函数第二参数为函数指针,则调用signal 函数的程序会阻塞(暂停在signal
函数这句),直至异步线程(进入函数指针)return
。程序将从暂停点恢复执行。
▶ 此外,进程之间可以互相通过系统调用kill
发送软中断信号
。
C++ signum.h
中通过 #define 定义了以下信号
2. 函数 signal
- 函数
signal
用于捕获信号,可指定信号处理的方式,函数声明如下:
void (*signal(int sig, void (*func)(int)))(int);
第一个参数
sig
指明了所要处理的信号类型,它可以取除了SIGKILL
和SIGSTOP
外的任何一种信号。
第二个参数描述了与信号关联的动作,下面将会对这三个参数进行讲解。
- 当程序收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:
I. 默认处理:对信号进行该信号的系统默认处理,第二参数为SIG_DFL
。
II. 忽略信号:忽略该信号,第二参数为SIG_IGN
。
III. Function handler:指定处理函数,由该函数来处理,第二参数为函数指针
。 - 若
signal
函数中第二参数(函数指针)中通过raise
发出与signal
函数对应信号类型相同的信号。程序将在signal
函数这成为死循环,自己发信号,自己捕获,进程暂停。
2.1 默认处理-SIG_DFL
SIG_DFL
对信号进行该信号的系统默认处理。
#include <chrono>
#include <iostream>
#include <csignal>
#include <thread>using namespace std;
int main() {signal(SIGINT, SIG_DFL);while(1){std::this_thread::sleep_for (std::chrono::seconds(1));std::cout << "hello world!" << endl;}return 0;
}
hello world!
hello world!
hello world!
^C
- 该程序包含一个死循环,循环内以一秒为间隔 打印语句。
SIGINT
信号代表由InterruptKey
产生,通常是CTRL +C
。执行上述代码时,按下CTRL + C
后程序退出。
2.2 忽略信号-SIG_IGN
SIG_IGN
表示忽略该信号。
#include <chrono>
#include <iostream>
#include <csignal>
#include <thread>using namespace std;
int main() {signal(SIGINT, SIG_IGN);while(1){std::this_thread::sleep_for (std::chrono::seconds(1));std::cout << "hello world!" << endl;}return 0;
}
hello world!
hello world!
^Chello world!
CChello world!
^Chello world!
hello world!
^\退出 (核心已转储)
- 该程序包含一个死循环,循环内以一秒为间隔 打印语句。
SIGINT
信号代表由InterruptKey
产生,通常是CTRL +C
。执行上述代码时,按下CTRL + C
后程序没有反应。- 如果我们想结束该程序可以按下
CTRL +\
,CTRL +\
组合键会产生SIGQUIT
信号,此信号并没有被忽略。
2.3 自定义函数
void (*signal(int sig, void (*func)(int)))(int);
- 第二参数为
函数指针
:当signal
函数捕获信号后,通过指定函数进行处理。 - PS: 此函数必须在
signal()
被调用前申明。
#include <chrono>
#include <iostream>
#include <csignal>
#include <thread>using namespace std;using namespace std;
void signalHandler( int signum ) {std::cout << "我来处理!" << std::endl;std::this_thread::sleep_for (std::chrono::seconds(5));
}int main() {signal(SIGINT, signalHandler); // 捕获 SIGINTstd::this_thread::sleep_for (std::chrono::seconds(2));std::cout << "程序结束." << endl;return 0;
}
^C我来处理!
程序结束.
- 该程序声明了信号类型为
SIGINT
的signal
函数,用于捕获SIGINT
信号。SIGINT
信号代表由InterruptKey
产生,通常是CTRL +C
- 当什么都不做时,程序会正常运行到结束。
- 如果在程序结束前按下
CTRL +C
,函数捕获SIGINT
信号,进入signalHandler
函数,mian
函数阻塞,直至signalHandler
函数运行结束,mian
函数打印后程序结束。
3. 函数 raise
- 函数
raise
产生一个信号sig
,并向当前正在执行的程序发送信号sig
,其声明如下:
int raise (int sig);
- 重点: 值得注意的是,raise发出的信号,可被当前进程中同类型型号的
signal
函数捕获。
#include <chrono>
#include <iostream>
#include <csignal>
#include <thread>using namespace std;
void signalHandler( int signum ) {std::cout << "我来处理!" << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));raise(SIGQUIT); // 3. 退出程序
}int main() {signal(SIGINT, signalHandler); // 1. signal函数,用于捕获 SIGINT 信号int i=0;while(++i){std::cout << "keep run...." << i << std::endl;if( i == 3 )raise(SIGINT); // 2. raise, 发送SIGINT 信号}return 0;
}
keep run…1
keep run…2
keep run…3
我来处理!
退出 (核心已转储)
- 可以看出当
signal
捕获信号后,main函数
对应的程序暂停,不再打印。 - 本测试中
signalHandler()
发出SIGQUIT
信号,进程结束。
4. 其他信号
linux
系统下,运行命令kill -l
可以看到Linux支持的信号列表。
一些常用的
Signal
如下:Signal DescriptionSIGALRM 用alarm函数设置的timer超时或setitimer函数设置的interval timer超时SIGBUS 某种特定的硬件异常,通常由内存访问引起SIGCANCEL 由Solaris Thread Library内部使用,通常不会使用SIGCHLD 进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略SIGCONT 当被stop的进程恢复运行的时候,自动发送SIGEMT 和实现相关的硬件异常SIGFPE 数学相关的异常,如被0除,浮点溢出,等等SIGFREEZE Solaris专用,Hiberate或者Suspended时候发送SIGHUP 发送给具有Terminal的Controlling Process,当terminal 被disconnect时候发送SIGILL 非法指令异常SIGINFO BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程SIGINT 由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程SIGIO 异步IO事件SIGIOT 实现相关的硬件异常,一般对应SIGABRTSIGKILL 无法处理和忽略。中止某个进程SIGLWP 由Solaris Thread Libray内部使用SIGPIPE 在reader中止之后写Pipe的时候发送SIGPOLL 当某个事件发送给Pollable Device的时候发送SIGPROF Setitimer指定的Profiling Interval Timer所产生SIGPWR 和系统相关。和UPS相关。SIGQUIT 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程SIGSEGV 非法内存访问SIGSTKFLT Linux专用,数学协处理器的栈异常SIGSTOP 中止进程。无法处理和忽略。SIGSYS 非法系统调用SIGTERM 请求中止进程,kill命令缺省发送SIGTHAW Solaris专用,从Suspend恢复时候发送SIGTRAP 实现相关的硬件异常。一般是调试异常SIGTSTP Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程SIGTTIN 当Background Group的进程尝试读取Terminal的时候发送SIGTTOU 当Background Group的进程尝试写Terminal的时候发送SIGURG 当out-of-band data接收的时候可能发送SIGUSR1 用户自定义signal 1SIGUSR2 用户自定义signal 2SIGVTALRM setitimer函数设置的Virtual Interval Timer超时的时候SIGWAITING Solaris Thread Library内部实现专用SIGWINCH 当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程SIGXCPU 当CPU时间限制超时的时候SIGXFSZ 进程超过文件大小限制SIGXRES Solaris专用,进程超过资源限制的时候发
C++ Signal(信号)相关推荐
- 组合键 发送指定信号_Django signal 信号机制的使用
Django中提供了"信号调度",用于在框架执行操作时解耦,当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作 一.Django中内置的 signal 类型主要包含以下几 ...
- iOS Mach异常和signal信号
摘要: 本着探究下iOS Crash捕获的目的,学习了下Crash捕获相关的Mach异常和signal信号处理,记录下相关内容,并提供对应的测试示例代码.Mach为XNU的微内核,Mach异常为最底层 ...
- signal信号详解
signal信号详解本文引用其它网站. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分 ...
- signal信号捕捉
[置顶]signal信号捕捉 分类: java初级2013-02-17 13:431074人阅读评论(0)收藏举报 Signal 顾名思义是信号的意思,为什么要用 ...
- python模块之signal信号
python模块之signal信号 1.简介 作用:发送和接收异步系统信号 信号是一个操作系统特性,它提供了一个途径可以通知程序发生了一个事件并异步处理这个事件.信号可以由系统本身生成,也可以从一个进 ...
- 【DBC专题】-2-CAN Signal信号的Multiplexor多路复用在DBC中实现
目录 0 关键字/术语描述 1有关"多路复用"概念 2 创建Message中"信号多路复用" 2.1 给Multiplexor Signal类型的信号创建合适的 ...
- 【DBC专题】-4-DBC文件中的Signal信号字节顺序Motorola和Intel介绍
目录 0 引言 1 小端(Intel)编码格式 1.1 Signal信号不跨字节 1.2 Signal信号跨字节 2 大端(Motorola)编码格式 2.1 Signal信号不跨字节 2.2 Sig ...
- iOS中Mach异常和signal信号介绍,以及当APP崩溃时做线程保活弹出程序异常提示框
我们经常会遇到APP闪退和崩溃的问题,那么我们应该通过什么变量去监听APP的异常呢?如何在程序崩溃时,保证程序不闪退,并给用户弹出一个提示框呢? 这是本文将要讲述的内容. 先介绍2个概念,Mach异常 ...
- signal信号的处理过程
signal信号的处理过程 mips架构下signal信号的处理.信号是linux下非常重要的部分,把这几天看的整理一下. 执行kill -l列出所有的信号 HUP INT QUIT ILL TRAP ...
- linux. signal信号,Linux下signal信号汇总
SIGHUP /* Hangup (POSIX). */ 终止进程 终端线路挂断 SIGINT /* Interrupt (ANSI). */ 终止进程 中断进程 Ctrl+C SIGQUIT /* ...
最新文章
- Linux 上的高可用中间件
- Spring JdbcTemplate快速入门
- java进程优先级,跨平台方式改变java进程优先级
- [css] 设置字体时为什么建议设置替换字体?
- Vue中 $ref 的用法
- android 通过访问 php 接受 or 传送数据
- 任正非之女姚安娜正式出道
- [Java 基础]控制语句
- Lingo基础语法笔记
- 小程序直播送礼物svga展示
- 木瓜移动:到底什么样的跨境SaaS服务商才是卖家更好的选择?
- python下一代工作流引擎_几大工作流引擎对比
- javascript-原生javascript实现类似节奏大师小游戏
- Windows10息屏快的问题解决办法(在更改屏幕和睡眠时间无效的情况下)
- u盘克隆服务器系统,只需4步!简单又快速的克隆U盘
- 自然语言处理模型:bert 结构原理解析——attention+transformer(翻译自:Deconstructing BERT)
- 实现css六边形边框,css 这种六边形的边框怎么画?
- 分享一个免费开源的视频剪辑软件(Shotcut)-附带安装教程以及中文设置
- 使用MVVM Swift UIKit RxSwift 写一个SpaceX 发射计划APP
- 【Window10】自定义菜单——显示桌面