首先来看一下一个简单的信号处理的例子

首先创建一个容纳信号对象的channel,channel的长度为1。

然后使用Notify注册信号处理,将Interrupt信号和channel关联起来。

进程挂在那里休眠,直到收到一个ctrl+c触发了Interrupt信号,channel里就会被塞进一条信号对象,<-c就会返回,打印信号对象然后退出程序。

上面这个例子是官方文档里提供的一个信号处理的简单例子。

值得注意的是这里的channel是非阻塞型channel,长度为1。那能不能是非阻塞型channel呢,能不能是长度为N的阻塞型channel呢?

我们先看看官方的文档里怎么说的

文档里的relay这个单词很有意思,它的英文是传达、转播,有点像代收的意思。

Notify会使得参数c[channel]来代收输入信号。如果信号参数sig未提供,就会代收所有类型的信号。否则只代收参数里提供的信号类型。

信号代收是非阻塞的,什么意思呢?

如果channel满了,被代收的信号就会被抛弃,因为没有空间容纳了。代收的过程等价于

如果channel的长度为1,当一连串的信号同时到达,只会有第一个信号会被代收,如果channel消费者没有来得及处理的话。

如果channel的长度为0,信号可能会丢失。比如下面的代码

我们在程序Sleep的时候狂按ctrl+c持续2秒,然后等待到5秒的Sleep结束,你会发现程序依然挂在那里,不会退出,这时需要再按一下ctrl+c才会退出。