我正在使用 linux(Ubuntu)和 bash。
我写了一个简单的 Go 程序。实际上是无限循环,每 20 秒打印一次文本。
package main
import (
"fmt"
"time"
)
func main() {
for {
fmt.Println("Hi from program 1")
time.Sleep(time.Second * 20)
}
}
SIGCHLD
首先,我使用以下命令为信号注册一个陷阱:
trap 'echo "hi you"' SIGCHLD
接下来,我使用以下命令异步启动一个程序(在后台):
./program &
我将其作为后台作业启动,以便 bash 可以使用终端。当我执行命令时:
kill -SIGSTOP process_id
陷阱被触发,并且消息“hi you”按预期显示。但是,当我运行:
kill -SIGCONT process_id
恢复该进程,进程继续运行(打印“Hi from program 1”),但不显示陷阱消息(“hi you”)。我kill
从另一个终端调用这些命令。
我在bash 文档中发现以下内容:
对于每个退出的子进程,都会执行 SIGCHLD 上的任何陷阱。
我可以将其理解为排他性的。换句话说,SIGCHLD
只有当子进程退出时,陷阱才会激活。如果是这样,我就会明白为什么我的例子不起作用。然而,SIGCHLD
当子进程被挂起时,陷阱也会被激活。
为什么会发生这种情况?恢复该过程也会产生信号SIGCHLD
,那么为什么在这种情况下陷阱不会触发?
相关问题。
这是 Bash 中期望的行为, 源代码中的以下注释对此进行了解释:
很难说这种行为的原因是什么,因为它是在 2001 年 Bash 开始使用 Git 之前引入的。