在goroutine中使用cmd.Command启动Web服务器,应用程序终止时进程不会关闭



我试图同时从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个goroutines,但仅在等待组中添加1个,因此您犯了一个错误,或者您的代码实际上只运行1个命令,其他2则不会运行。如果要3,请将3添加到等待组。

  • 我在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 %sn", command)
        cmd := createCommand(ctx, command)
        cmds = append(cmds, cmd)
        go func (c *exec.Cmd, name string) {
        fmt.Printf("Process command %sn", name)
            defer wg.Done()
            c.Start()
            c.Wait()
        fmt.Printf("Finish command %sn", 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

相关内容

最新更新