我正在尝试从 go 中同时生成多个命令,然后在第一个任务完成时将它们全部关闭。
问题是,有时在生成 dotnet 服务器并使用 sudo 运行我的项目时,生成的进程不会在应用程序终止时终止。
为什么会发生这种情况以及如何让进程终止?
大概是这样
func createCommand(command string) {
var cmd *exec.Cmd
cmd = exec.Command("/bin/bash", "-c", command)
return cmd
}
func main() {
commands := []string{
"cd server1 && dotnet run",
"cd server2 && dotnet run",
"sleep 10 && echo complete"
}
var wg sync.WaitGroup
wg.Add(1)
var cmds []*exec.Cmd
defer func() {
fmt.Println("Process clean up")
for _, cmd := range cmds {
cmd.Process.Kill()
}
}()
for _, command := range commands {
cmd := createCommand(command)
cmds = append(cmds, cmd)
go func (c string) {
defer wg.Done()
c.Start()
c.Wait()
}(cmd)
}
wg.Wait()
}
最佳答案
我不确定 sudo 的问题。但是您的代码存在这些问题:
您正在生成 3 个 goroutine,但只将 1 个添加到 WaitGroup ,所以您可能犯了一个错误,或者您的代码实际上只运行了 1 个命令,其他 2 个不会运行。如果要 3 个,请将 3 个添加到 WaitGroup 。
我在 go 文档中找不到 cmd.Process.Kill(),但我看到了 os.Process.Kill。但是,建议使用上下文来取消进程。有了上下文,你的命令肯定会被终止。
下面的代码展示了我的想法:
package main
import (
"os/exec"
"fmt"
"sync"
"context"
"time"
)
func createCommand(ctx context.Context, command string) *exec.Cmd{
return exec.CommandContext(ctx, "/bin/bash", "-c", command)
}
func main() {
commands := []string{
"sleep 1000000 && echo complete",
"sleep 1000000 && echo complete",
"sleep 10 && echo complete",
}
var wg sync.WaitGroup
wg.Add(3)
var cmds []*exec.Cmd
ctx, cancel := context.WithTimeout(context.Background(), 20 * time.Second)
defer func() {
fmt.Println("Process clean up")
cancel()
}()
for _, command := range commands {
fmt.Printf("Create command %s\n", command)
cmd := createCommand(ctx, command)
cmds = append(cmds, cmd)
go func (c *exec.Cmd, name string) {
fmt.Printf("Process command %s\n", name)
defer wg.Done()
c.Start()
c.Wait()
fmt.Printf("Finish command %s\n", name)
}(cmd, command)
}
wg.Wait()
}
输出是:
Create command sleep 1000000 && echo complete
Create command sleep 1000000 && echo complete
Create command sleep 10 && echo complete
Process command sleep 10 && echo complete
Finish command sleep 10 && echo complete
Process command sleep 1000000 && echo complete
Finish command sleep 1000000 && echo complete
Process command sleep 1000000 && echo complete
Finish command sleep 1000000 && echo complete
Process clean up
关于go - 在 goroutine 中使用 cmd.Command 启动 Web 服务器,应用程序终止时进程不会关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53842344/