再看看信号处理。这个写法有点像 erlang 了。
sig := (<-signal.Incoming).(signal.UnixSignal)
signal.Incoming 是一个 <-chan Signal,意味着 sig := <-signal.Incoming 可以得到一个 signal.Signal,然后 .(signal.UnixSignal) 做一下强制转换。
-----------------------------------------
package main
import (
"fmt"
"os/signal"
)
func main() {
for {
switch sig := (<-signal.Incoming).(signal.UnixSignal); sig {
case signal.SIGUSR1:
fmt.Println("SIGUSR1")
case signal.SIGUSR2:
fmt.Println("SIGUSR2")
default:
fmt.Println("Other")
}
}
}
-------------------------------------------
看一下 os.signal 里面如何实现的:
---------------------------- os/signal/signal.go --------------------------
// Incoming is the global signal channel.
// All signals received by the program will be delivered to this channel.
var Incoming <-chan Signal
func process(ch chan<- Signal) {
for {
var mask uint32 = runtime.Sigrecv()
for sig := uint(0); sig < 32; sig++ {
if mask&(1<<sig) != 0 {
ch <- UnixSignal(sig)
}
}
}
}
func init() {
runtime.Siginit()
ch := make(chan Signal) // Done here so Incoming can have type <-chan Signal
Incoming = ch
go process(ch)
}
------------------------------------------------------------------------------
通过 init(),在 package 初始化的时候,go process(ch) 启动一个 light-weight process,从 runtime 那获取 signal,并发给 Incoming。
评论