在goroutine中使用exec.CommandContext时如何调用cancel()

在goroutine中使用exec.CommandContext时如何调用cancel(),go,Go,我想按需取消正在运行的命令,为此,我正在尝试,目前正在尝试: 主程序包 进口( “上下文” “日志” “os/exec” “时间” ) func运行(退出chan结构{}){ ctx,cancel:=context.WithCancel(context.Background()) cmd:=exec.CommandContext(ctx,“睡眠”,“300”) 错误:=cmd.Start() 如果错误!=零{ log.Fatal(错误) } go func(){ log.Println(“等待

我想按需取消正在运行的命令,为此,我正在尝试,目前正在尝试:

主程序包
进口(
“上下文”
“日志”
“os/exec”
“时间”
)
func运行(退出chan结构{}){
ctx,cancel:=context.WithCancel(context.Background())
cmd:=exec.CommandContext(ctx,“睡眠”,“300”)
错误:=cmd.Start()
如果错误!=零{
log.Fatal(错误)
}
go func(){
log.Println(“等待cmd退出”)
err:=cmd.Wait()
如果错误!=零{
log.Println(错误)
}
}()
go func(){
挑选{

案例在Go中,如果到达
main
方法(在
main
包中)的末尾,程序将停止。Go语言规范中描述了此行为,强调如下(我自己):

程序执行首先初始化
main
包,然后调用函数
main
。当该函数调用返回时,程序退出。它不会等待其他(非主)goroutine完成。


缺陷

我将考虑每一个示例及其相关的控制流缺陷。您将找到下面的GO游戏场的链接,但是这些示例中的代码将不会在限制性的游乐场沙盒中执行,因为<代码>睡眠>代码>无法执行。复制和粘贴到您自己的环境中进行测试。

多goroutine示例
案例您必须在
等待
之后写入
退出
,以发出远程进程终止的信号。在主程序中,在选择之后,在
退出
上添加读取操作,以捕获新信号并退出程序。
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{}{}
    }
}