runc源码中:
// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
// Handle and forward signals.
for s := range h.signals { / 这里会一直阻塞吗?
switch s {
case unix.SIGWINCH:
// ...
case unix.SIGCHLD:
// ...
case unix.SIGURG:
// SIGURG is used by go runtime for async preemptive
// scheduling, so runc receives it from time to time,
// and it should not be forwarded to the container.
// Do nothing.
default:
us := s.(unix.Signal)
logrus.Debugf("forwarding signal %d (%s) to %d", int(us), unix.SignalName(us), pid1)
if err := unix.Kill(pid1, us); err != nil {
logrus.Error(err)
}
}
}
return -1, nil
}
答案是:是的, 会一直阻塞。 系统会把所有Signal全部转发给Runc.
这里给出一个简单的示例证明一下:对channel执行迭代操作会阻塞。
package main
import (
"fmt"
"golang.org/x/sys/unix"
"os"
"os/signal"
)
func main() {
s := make(chan os.Signal, 1)
signal.Notify(s)
for c := range s { // 会一直循环
switch c {
default:
us := c.(unix.Signal)
fmt.Println(us.String())
}
}
}
一个更加简单的例子:
package main
import (
"fmt"
"time"
)
func main() {
s := make(chan bool, 1)
go func() {
for{
s<- false
time.Sleep(5*time.Second)
}
}()
for c := range s { // 会一直阻塞
switch c {
default:
fmt.Println(c)
}
}
}