每个信号的名字都以字符“SIG”开头,并与一个特定的数字编码相对应
这些信号在头文件`/usr/include/i386-linux-gnu/bits/signum.h`中被定义为正整数
通过信号,进程可以响应各种系统事件或用户操作,从而实现复杂的交互和错误处理机制
本文将详细介绍Linux信号的定义、分类、用途以及相关的编程接口
一、信号的定义与分类 在Linux中,信号被分为两大类:不可靠信号(非实时信号)和可靠信号(实时信号)
不可靠信号编号为1到31,是传统UNIX系统所支持的信号
这类信号不支持排队,如果多个相同类型的信号在短时间内发送到同一个进程,可能会造成信号的丢失
而可靠信号编号为34到63,是后来扩充的信号,支持排队,可以确保所有信号都被正确处理
二、常见信号及其用途 1.SIGHUP -描述:当用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一会话期(Session)内的各个作业,这时它们与控制终端不再关联
-用途:前台进程组和后台有终端输出的进程会收到SIGHUP信号,默认操作为终止进程
对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件
2.SIGINT -描述:在用户键入INTR字符(通常是Ctrl+C)时发出,用于通知前台进程组终止进程
-用途:常用于中断正在运行的程序
3.SIGQUIT -描述:和SIGINT类似,但由QUIT字符(通常是Ctrl+)来控制
进程在因收到SIGQUIT退出时会产生core文件,在这个意义上类似于一个程序错误信号
-用途:用于生成core文件,便于调试
4.SIGILL -描述:执行了非法指令,通常是因为可执行文件本身出现错误,或者试图执行数据段,堆栈溢出时也有可能产生这个信号
-用途:指示程序执行了非法的指令
5.SIGTRAP -描述:由断点指令或其他陷阱(Trap)指令产生,由调试器(Debugger)使用
-用途:用于调试过程中捕获断点
6.SIGABRT -描述:程序自己发现错误并调用abort时产生
-用途:指示程序异常终止
7.SIGBUS -描述:非法地址,包括内存地址对齐(Alignment)出错
例如,访问一个四个字长的整数,但其地址不是4的倍数
-用途:指示内存地址访问错误
8.SIGFPE -描述:在发生致命的算术运算错误时发出,不仅包括浮点运算错误,还包括溢出及除数为0等其他所有的算术错误
-用途:指示算术运算错误
9.SIGKILL -描述:用来立即结束程序的运行,本信号不能被阻塞、处理和忽略
-用途:强制终止进程
10. SIGUSR1 和 SIGUSR2 -描述:用户自定义信号
-用途:用户可以根据需要定义这些信号,用于进程间的自定义通信
11. SIGTERM -描述:程序结束(terminate)信号,与SIGKILL不同的是该信号可以被阻塞和处理,通常用来要求程序自己正常退出
-用途:请求程序正常终止
12. SIGSTOP 和 SIGTSTP -描述:用于停止进程的执行
SIGSTOP不能被阻塞、处理或忽略,而SIGTSTP可以由用户键入SUSP字符(通常是Ctrl+Z)来触发,并且可以被处理和忽略
-用途:暂停进程的执行
13. SIGCONT -描述:让一个停止(stopped)的进程继续执行
本信号不能被阻塞
-用途:恢复被暂停的进程
14. SIGCHLD -描述:子进程结束时,父进程会收到这个信号
-用途:通知父进程子进程的结束状态
15. SIGALRM -描述:时钟定时信号,计算的是实际的时间或时钟时间
-用途:用于定时器功能
16. SIGPIPE -描述:向一个没有读进程的管道写数据时发出
-用途:指示管道破裂
17. SIGWINCH -描述:窗口大小改变时发出
-用途:用于调整终端窗口大小时的处理
三、信号的处理与编程接口 在Linux中,处理信号的主要编程接口包括signal()、sigaction()以及一系列与信号集操作相关的函数,如sigemptyset()、sigfillset()、sigaddset()等
1.signal() -功能:设置信号的处理函数
-用法:`void (signal(int signum,void (handler)(int)))(int);` -参数:signum为信号编号,handler为处理函数
-返回值:返回以前的信号处理函数指针,出错时返回SIG_ERR
2.sigaction() -功能:更强大和灵活的信号处理接口,用于替代signal()
-用法:`int sigaction(int signum, const struct sigactionact, struct sigaction oldact);` -参数:signum为信号编号,act为新的信号处理动作,oldact用于保存旧的信号处理动作
-返回值:成功时返回0,出错时返回-1并设置errno
3.信号集操作函数 -sigemptyset():初始化信号集为空
-sigfillset():初始化信号集包含所有已定义的信号
-sigaddset():将指定信号添加到信号集中
-sigdelset():从信号集中删除指定信号
-sigismember():判断指定信号是否属于信号集
-sigprocmask():设置进程的信号屏蔽字,用于阻塞或解除阻塞信号
-sigpending():获取当前被阻塞且停留在待处理状态的信号集
-sigsuspend():替换进程的信号屏蔽字并挂起进程的执行,直到捕获到一个信号为止
四、信号的应用场景 1.进程控制 - 使用SIGKILL强制终止无法响应SIGTERM的进程
- 使用SIGSTOP和SIGCONT暂停和恢复进程的执行
2.错误处理 - 捕获SIGSEGV、SIGFPE等信号,生成core文件,便于调试程序
- 捕获SIGILL信号,处理非法指令错误
3.定时器功能 - 使用SIGALRM信号实现定时器功能,例如定时清理资源、定时检查状态等
4.进程间通信 - 使用SIGUSR1和SIGUSR2等用户自定义信号,实现进程间的自定义通信
5.终端交互 - 捕获SIGINT、SIGQUIT、SIGTERM等信号,处理用户的中断和终止请求
- 捕获SIGTSTP、SIGTTIN、SIGTTOU等信号,处理终端的暂停和恢复请求
五、总结 Linux信号机制是一种强大且灵活的进程间通信手段,通过信号,进程可以响应各种系统事件或用户操作,实现复杂的交互和错误处理机制
本文详细介绍了Linux信号的定义、分类、用途以及相关的编程接口,希望能为读者深入理解Linux信号机制提供帮助
在实际开发中,合理利用信号机制可以极大地提高程序的健壮性和可维护性