1.信号介绍
- 信号是内容受限的一种异步通信机制,是事件发生时对进程的通信机制,用来通知进程发生了异步事件。
- 信号有时候也称为软件中断,它在软件层次上是对中断机制的一种模拟,可以打断程序执行的正常流程。信号对于进程来说就是不可预测的异步的事件。信号本质上是事先定义好的int型数字编号(从1开始顺序展开)。
2.信号的产生和处理
2.1信号的产生
- 1.硬件异常,硬件检测到一个错误并通知内核,然后内核发送相应信号给相关进程。
- 2.用户在终端按下能够产生信号的中断特殊字符(中断字符:ctl+c,暂停字符:ctl+z)。
- 3.某种软件条件满足后产生软件信号。
2.2信号的处理
- 忽略信号:内核将信号丢弃,信号对进程没有任何影响。
- 终止进程:系统产生异常时内核将进程终止。
- 捕获信号:信号绑定了一个函数,执行信号处理程序(用于响应传递而来的信号而执行适当任务)。
- 默认处理:当前进程没有明显的管这个信号,默认:忽略或终止进程。
3.常见信号类型和行为
完整的信号类型可以在/usr/include/x86_64-linux-gnu/bits目录下的signum.h文件中查看。
/* Signals. */
#define SIGHUP 1 /* Hangup (POSIX). */
#define SIGINT 2 /* Interrupt (ANSI). */
#define SIGQUIT 3 /* Quit (POSIX). */
#define SIGILL 4 /* Illegal instruction (ANSI). */
#define SIGTRAP 5 /* Trace trap (POSIX). */
#define SIGABRT 6 /* Abort (ANSI). */
#define SIGIOT 6 /* IOT trap (4.2 BSD). */
#define SIGBUS 7 /* BUS error (4.2 BSD). */
#define SIGFPE 8 /* Floating-point exception (ANSI). */
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
#define SIGSEGV 11 /* Segmentation violation (ANSI). */
#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
#define SIGPIPE 13 /* Broken pipe (POSIX). */
#define SIGALRM 14 /* Alarm clock (POSIX). */
#define SIGTERM 15 /* Termination (ANSI). */
#define SIGSTKFLT 16 /* Stack fault. */
#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
#define SIGCHLD 17 /* Child status has changed (POSIX). */
#define SIGCONT 18 /* Continue (POSIX). */
#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
#define SIGTSTP 20 /* Keyboard stop (POSIX). */
#define SIGTTIN 21 /* Background read from tty (POSIX). */
#define SIGTTOU 22 /* Background write to tty (POSIX). */
#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
#define SIGIO 29 /* I/O now possible (4.2 BSD). */
#define SIGPWR 30 /* Power failure restart (System V). */
#define SIGSYS 31 /* Bad system call. */
#define SIGUNUSED 31
#define _NSIG 65 /* Biggest signal number + 1
(including real-time signals). */
下面总结几个常见的信号:
| 信号类型 | 信号值 | 信号行为 |
|---|---|---|
| SIGINT | 2 | Ctrl+C时OS送给前台进程组中每个进程 |
| SIGABRT | 6 | 调用abort函数,进程异常终止 |
| SIGIO/SIGPOLL | 8 | SIGIO指示一个异步IO事件,SIGPLOO派生自systemv,与SIGIO同义 |
| SKILL | 9 | 杀死进程的终极方法 |
| SIGSEGV | 11 | 无效内存引用时OS发出该信号 |
| SIGPIPE | 13 | 涉及管道和socket |
| SIGALARM | 14 | 涉及alarm函数的实现 |
| SIGTERM | 15 | kill命令发送的OS默认终止信号 |
| SIGCHLD | 17 | 子进程终止时OS向其父进程发此信号 |
| SIGUSR1 | 10 | 用户自定义信号 |
| SIGUSR2 | 12 | 用户自定义信号 |
4.信号处理系统调用
4.1signal()函数
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signal()函数注册当前进程对某个信号的处理方法, 参数signum是接受到的信号类型,参数handler是个函数指针,就是信号处理方法函数。signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数。
singnal()在unix和linux不同版本的表现行为可能是不一样的,所以应该避免使用这个函数,可以使用sigaction()代替。sigaction()比signal()更具有可移植性。
4.2signal()函数
#include <signal.h>
int sigaction(int signum,
const struct sigaction *act,
struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sigaction可以一次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数不能单独获取旧的捕获函数而必须在设置新的捕获函数的同时才获取旧的捕获函数。
本文深入解析Linux中的信号机制,包括信号的产生、处理方式、常见信号类型及其行为,以及信号处理的系统调用如signal()和sigaction()函数。信号作为进程间通信的重要手段,本文详尽介绍了其在Linux系统中的运作原理。
7031

被折叠的 条评论
为什么被折叠?



