- 操作系统信号,英文signal,简称信号。
- 是IPC中唯一一种异步的通信方法。
- 它的本质是用软件来模拟硬件的中断机制。
- 信号用来通知某个进程有某个事件发生了。例如,在命令行终端按下某些快捷键,就会挂起或停止正在运行的程序。另外,通过kill命令杀死某个进程的操作也有信号的参与。
- 每一个信号都有一个以“SIG”为前缀的名字,例如SIGINT,SIGQUIT,SIGKILL等等。
- 在操作系统内部,这些信号都由正整数表示,这些正整数称为信号编号。
在Linux操作系统中,通过kill -l来查看所有的信号。
信号如何分类?- Linux支持的信号有62种。注意:没有编号为32和33的信号。
- 编号从1到31的信号属于标准信号。
- 编号从34到64的信号称为实时信号。
对于同一个进程来说,每种标准信号只会被记录并处理一次。
如果发送给某一个进程的标准信号有多个,他们的处理顺序是不确定。
- 实时信号解决了标准信号的两大问题。同种类的实时信号都可以记录在案,并且他们可以按照信号的发送顺序被处理。
- 已成为事实的标准信号无法被替换,所有标准信号和实时信号共存。
- 键盘输入,比如ctrl+c
- 硬件故障
- 系统函数调用
- 软件中的非法运算
- 忽略
- 捕捉
- 执行默认操作
- 终止进程
- 忽略该信号
- 终止进程并保存内存信息
- 停止进程
- 恢复进程(若进程已停止)
- SIGKILL和SIGSTOP这两种信号不能被自行处理,也不能被忽略,对它们的操作只能是系统默认操作。
- 根本原因是为了向系统超级用户提供使进程终止或停止的可靠方法。
- 这种保障不论对应用程序还是操作系统来说,都是非常有必要的。
package main
import (
"fmt"
"os"
"os/signal"
)
func main() {
// 创建一个管道,是Notify的第一个参数的类型
sigRecv := make(chan os.Signal, 1)
// 发送通知
signal.Notify(sigRecv)
// 从管道中读取信号
for sig := range sigRecv {
fmt.Printf("Received a signal: %sn", sig)
}
}
示例2:取消通知
package main
import (
"fmt"
"os"
"os/signal"
)
func main() {
// 创建一个管道,是Notify的第一个参数的类型
sigRecv := make(chan os.Signal, 1)
// 发送通知
signal.Notify(sigRecv)
// 从管道中读取信号
for sig := range sigRecv {
fmt.Printf("Received a signal: %sn", sig)
// 取消
signal.Stop(sigRecv)
close(sigRecv)
}
}



