gpt4 book ai didi

go - 在 golang : Prevent child processes to receive signals from calling process

转载 作者:IT王子 更新时间:2023-10-29 01:21:35 27 4
gpt4 key购买 nike

给出如下代码:

package main
import (
"os"
"fmt"
"os/exec"
"os/signal"
"syscall"
)

const NUMBER_OF_PEASANTS = 3

func createPeasants() map[string]*exec.Cmd {
peasants := map[string]*exec.Cmd{}
for i := 0; i < NUMBER_OF_PEASANTS; i++ {
name := fmt.Sprintf("peasant#%d", i + 1)
fmt.Printf("[master] Start %s...\n", name)
cmd := exec.Command(os.Args[0], name)
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
if err := cmd.Start(); err != nil {
panic(err)
}
peasants[name] = cmd
}
return peasants
}

func masterWaitForSignal(c chan os.Signal) {
for true {
s := <-c
fmt.Printf("[master] Got signal %v but still running...\n", s)
}
}

func peasantWaitForSignal(name string, c chan os.Signal) {
s := <-c
fmt.Printf("[%s] Got signal %v and will exit not with code 66\n", name, s)
os.Exit(66)
}

func waitForPeasants(peasants map[string]*exec.Cmd) {
for name, peasant := range peasants {
if err := peasant.Wait(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus := exitError.Sys().(syscall.WaitStatus)
fmt.Printf("[master] %s ended with exit code %d.\n", name, waitStatus.ExitStatus())
} else {
panic(err)
}
}
}
}

func actAsMaster() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

peasants := createPeasants()

fmt.Printf("[master] Started.\n")
go masterWaitForSignal(c)
waitForPeasants(peasants)
fmt.Printf("[master] Done.\n")
}

func actAsPeasant(name string) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

fmt.Printf("[%s] Started.\n", name)
peasantWaitForSignal(name, c)
fmt.Printf("[%s] Done.\n", name)
}

func main() {
if len(os.Args) > 1 {
actAsPeasant(os.Args[1])
} else {
actAsMaster()
}
}

当我运行代码并按下 [Ctrl]+[C](在它运行时)时,它产生了以下输出:

$ go run signaldemo.go 
[master] Start peasant#1...
[master] Start peasant#2...
[master] Start peasant#3...
[peasant#1] Started.
[master] Started.
[peasant#2] Started.
[peasant#3] Started.
^C[peasant#2] Got signal interrupt and will exit not with code 66
[peasant#1] Got signal interrupt and will exit not with code 66
[master] Got signal interrupt but still running...
[master] peasant#1 ended with exit code 66.
[master] peasant#2 ended with exit code 66.
[peasant#3] Got signal interrupt and will exit not with code 66
[master] peasant#3 ended with exit code 66.
[master] Done.

如何防止 child 收到中断信号?但我不想重写 child 。需要更改调用过程。

最佳答案

默认情况下,子进程在同一个进程组中启动,当您按下 ctrl+c 时,您的 shell 会立即向所有进程发送信号。这是 shell 在您中断程序时尝试清理的默认行为。

子进程不会接收直接发送给父进程的信号。

如果你想阻止 ctrl+c 行为,你可以使用 SetpgidPgid 强制子进程在它们自己的进程组中启动 syscall.SysProcAttr 中的字段在开始流程之前。

cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pgid: 0,
}

关于go - 在 golang : Prevent child processes to receive signals from calling process,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35433741/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com