我试图同时从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