linux signal 详解
目录
参考https://man7.org/linux/man-pages/man7/signal.7.html
signal是什么
定位
- 进程间通信机制
作用
- 给进程传递关键控制信息
用法
signal
个数种类固定,确定对应信号的handler
即可
谁产生的signal
也是改变程序状态的原因,主要以下三种
-
用户在终端与程序交互
-
程序异常
-
系统调用
-
kill
Sends a signal to a specified process, to all members of a specified process group, or to all processes on the system.
-
raise
Sends a signal to the calling thread.
-
...
-
各个信号的具体产生原因
Signal Standard Action Comment
SIGABRT P1990 Core Abort signal from abort(3)
SIGALRM P1990 Term Timer signal from alarm(2)
SIGBUS P2001 Core Bus error (bad memory access)
SIGCHLD P1990 Ign Child stopped or terminated
SIGCLD - Ign A synonym for SIGCHLD
SIGCONT P1990 Cont Continue if stopped
SIGEMT - Term Emulator trap
SIGFPE P1990 Core Floating-point exception
SIGHUP P1990 Term Hangup detected on controlling terminal or death of controlling process
SIGILL P1990 Core Illegal Instruction
SIGINFO - A synonym for SIGPWR
SIGINT P1990 Term Interrupt from keyboard
SIGIO - Term I/O now possible (4.2BSD)
SIGIOT - Core IOT trap. A synonym for SIGABRT
SIGKILL P1990 Term Kill signal
SIGLOST - Term File lock lost (unused)
SIGPIPE P1990 Term Broken pipe: write to pipe with no readers; see pipe(7)
SIGPOLL P2001 Term Pollable event (Sys V); synonym for SIGIO
SIGPROF P2001 Term Profiling timer expired
SIGPWR - Term Power failure (System V)
SIGQUIT P1990 Core Quit from keyboard
SIGSEGV P1990 Core Invalid memory reference
SIGSTKFLT - Term Stack fault on coprocessor (unused)
SIGSTOP P1990 Stop Stop process
SIGTSTP P1990 Stop Stop typed at terminal
SIGSYS P2001 Core Bad system call (SVr4); see also seccomp(2)
SIGTERM P1990 Term Termination signal
SIGTRAP P2001 Core Trace/breakpoint trap
SIGTTIN P1990 Stop Terminal input for background process
SIGTTOU P1990 Stop Terminal output for background process
SIGUNUSED - Core Synonymous with SIGSYS
SIGURG P2001 Ign Urgent condition on socket (4.2BSD)
SIGUSR1 P1990 Term User-defined signal 1
SIGUSR2 P1990 Term User-defined signal 2
SIGVTALRM P2001 Term Virtual alarm clock (4.2BSD)
SIGXCPU P2001 Core CPU time limit exceeded (4.2BSD); see setrlimit(2)
SIGXFSZ P2001 Core File size limit exceeded (4.2BSD); see setrlimit(2)
SIGWINCH - Ign Window resize signal (4.3BSD, Sun)
Real-time signals
范围
- SIGRTMIN - SIGRTMAX 之间
特性
- 全部隶属未定义信号,用于用户定义,默认终止程序
谁发给的进程
- 产生信号的原因多样
- 产生信号的主体多样
- 发送信号给进程的主体确定,是在内核态操作系统发送的
什么时候发的
- 时机确定:内核态 -> 进程用户态
- 系统调用返回
- 操作系统进程调度到该进程
- 当内核态转变用户态,操作系统会检查是否有pending信号在队列
- 信号处理在用户态处理
- 若一次内核态到用户态的转变,产生多次某一标准信号,只会保留一次
- 若一次内核态到用户态的转变,产生多个标准信号,则顺序未定义
- 若一次内核态到用户态的转变,产生多次某一Real-time signals, 多次都会保留
- 若一次内核态到用户态的转变,产生多个Real-time signals,则顺序由小到大发送给进程
- 若一次内核态到用户态的转变,产生Real-time signals和标准信号,标准信号优先
如何处理signal
默认处理行为
Term Default action is to terminate the process.
Ign Default action is to ignore the signal.
Core Default action is to terminate the process and dump core
Stop Default action is to stop the process.
Cont Default action is to continue the process if it is currently stopped.
用户可以自定义信号处理函数
如何自定义处理函数
注册自定义信号处理函数
#include <iostream>
#include <signal.h>
#include <unistd.h>
volatile bool s_quit = false;
void SignalHandler(int signal) {
std::cout << "Receive signal : " << signal << "\n";
if(signal == SIGINT) {
std::cout << "Receive Ctrl + C!\n";
} else if (signal == SIGRTMIN) {
s_quit = true;
std::cout << "Exit gracefully!\n";
}
}
int main(int arg, char *args[]) {
//注册信号
signal(SIGINT, SignalHandler);
signal(SIGRTMIN, SignalHandler);
while (!s_quit) {
sleep(1);
}
return 0;
}
volatile
关键字
原因
- 单一程序编译时,编译优化可能使得s_quit不总是访问内存值,由此可能出现不能及时捕获内存值变化
作用
- 阻止编译优化,每次访问时访问内存,及时捕获值变化