概念
- 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
- 信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。
- 如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被 取消时才被传递给进程。
用户进程对信号的响应方式:
- 忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即 SIGKILL 及 SIGSTOP。
- 捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。
- 执行缺省操作:Linux对每种信号都规定了默认操作
标准信号
linux 支持一些标准信号,以及它们的默认操作。
1 | 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) |
下面是默认操作的含义:
- Term 默认操作是终止进程.
- Ign 默认操作是忽略信号.
- Core 默认操作是终止进程并 dump core 文件.
- Stop 默认操作是停止进程.
- Cont 默认操作是如果进程停止了,继续它的执行
可以通过 sigaction(2) 或者 signal(2) 函数修改进程对信号的默认行为。
相关函数
发送信号
- raise(3) 向调用此函数的线程发送信号
- kill(2) 向指定的进程、进程组或者系统中所有进程发送信号
- pidfd_send_signal(2) 向一个通过 PID fd 指定的进程发送信号
- killpg(3) 向一个进程组中的所有进程发送信号
- pthread_kill(3) 向一个同进程的指定的 POSIX 线程发送信号
- tgkill(2) 向指定进程的指定线程发送信号(pthread_kill基于此内核函数实现)
- sigqueue(3) 将实时信号和一部分附带数据发送到指定的进程
等待信号捕获
下面的函数会暂停调用它们的线程,直到收到一个信号,或者一个未处理的信号终止进程。
- pause(2) 暂停执行直到任意信号被捕获
- sigsuspend(2) 暂时修改信号 mask,并暂停执行,直到 mask 之外的信号被捕获
同步接收信号
除了使用 sigaction 等函数设置信号回调之外,还可以通过同步等待接收信号的方式来处理信号。
- sigwaitinfo(2)、sigtimedwait(2)、sigwait(3) 会暂停执行,直到被指定的信号集合中的一个被触发。信号捕获后,这几个函数都会返回捕获的信号值,
- signalfd(2) 返回一个可以读取到接收到的信号的 fd。使用 read 从 fd 读取信号值时,阻塞进程,直到指定的信号触发。
示例代码
监听信号
1 | #include <stdio.h> |
发送信号
1 | #include <stdio.h> |
参考文档:
- https://man7.org/linux/man-pages/man2/signal.2.html
- https://man7.org/linux/man-pages/man7/signal.7.html
- https://cloud.tencent.com/developer/article/1877910
- https://www.cnblogs.com/electronic/p/10939769.html
本文链接:https://www.zoucz.com/blog/2022/07/07/6d7977c0-a3b1-11ee-b5fb-135d9fa49e8f/