【发布时间】:2018-09-15 15:45:39
【问题描述】:
我想按需取消正在运行的命令,为此,我正在尝试,exec.CommandContext,目前正在尝试:
https://play.golang.org/p/0JTD9HKvyad
package main
import (
"context"
"log"
"os/exec"
"time"
)
func Run(quit chan struct{}) {
ctx, cancel := context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, "sleep", "300")
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
go func() {
log.Println("waiting cmd to exit")
err := cmd.Wait()
if err != nil {
log.Println(err)
}
}()
go func() {
select {
case <-quit:
log.Println("calling ctx cancel")
cancel()
}
}()
}
func main() {
ch := make(chan struct{})
Run(ch)
select {
case <-time.After(3 * time.Second):
log.Println("closing via ctx")
ch <- struct{}{}
}
}
我面临的问题是cancel()被调用但进程没有被杀死,我的猜测是主线程先退出,不要等待cancel()正确终止命令,主要是因为如果我在main 函数的末尾使用time.Sleep(time.Second),它会退出/终止正在运行的命令。
关于我如何wait 确保在退出之前不使用sleep 命令已被终止的任何想法?成功杀死命令后,cancel() 可以在频道中使用吗?
在尝试使用单个 goroutine 时,我尝试了这个:https://play.golang.org/p/r7IuEtSM-gL 但cmd.Wait() 似乎一直阻塞select 并且无法调用cancel()
【问题讨论】:
-
您必须在
Wait之后写上quit才能发出远程进程终止的信号。在您的 main 中,在选择之后,在quit上添加一个读取操作以捕获该新信号并退出您的程序。
标签: go