我正在使用 Linux(ubuntu)。
当我man 7 signal
在终端中输入 (manual 2020-12-21) 时,我发现 SIGCHLD 出现以下情况:
SIGCHLD P1990 Ign Child stopped or terminated
因此,它表明SIGCHLD
仅在这两种情况下才会生成信号。它并未说明子进程何时继续运行。
然而,在 POSIX 中,它规定如下:
SIGCHLD Child process terminated, stopped,
[XSI] or continued.
因此,当 OS 支持 XSI 时,子进程继续时也会生成此信号。我还编写了一些简单的子进程/父进程程序,可以确认这一点。既然 Linux 支持 XSI,为什么手册中不包括 SIGCHLD 的“继续”场景?如果手册不完整(或者我不明白它的用途),那么手册的目的是什么?
此外,我发现以下有关SIGCHLD 的答案不完整。
下面是代码。这是一段简单的 golang 代码。父进程通过经典的 fork/exec 启动子进程。然后它为 SIGCHLD 信号注册一个处理程序,就这样。父进程和子进程每 10 秒打印一条消息。构建两个程序后,我通过命令运行它们。我通过和控制子进程的./parent
行为(T
<->状态) 。R/S
kill -SISTOP child_process_id
kill -SIGCONT child_process_id
家长:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
attr := &syscall.ProcAttr{
Files: []uintptr{0, 1, 2},
}
_, err := syscall.ForkExec("./child/child", []string{"child"}, attr)
if err != nil {
fmt.Println("Error:", err)
return
}
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGCHLD)
go func() {
for {
select {
case <-ch:
fmt.Println("SIGNAL")
}
}
}()
for {
fmt.Println("Parent is live")
time.Sleep(10 * time.Second)
}
}
孩子:
package main
import (
"fmt"
"time"
)
func main() {
for {
fmt.Println("hi from child")
time.Sleep(time.Second * 10)
}
}