标签:[] 子进程 协程 cas pid ann goroutine 命令 上下文
package main
import (
"fmt"
"os/exec"
)
func main() {
var (
cmd *exec.Cmd
err error
)
cmd = exec.Command("/bin/bash", "-c", "echo 1")
err = cmd.Run()
fmt.Println(err)
}
package main
import (
"fmt"
"os/exec"
)
func main() {
var (
cmd *exec.Cmd
output []byte
err error
)
// 生成Cmd
cmd = exec.Command("/bin/bash", "-c", "ls -la /")
// 执行了命令, 捕获了子进程的输出( pipe )
if output, err = cmd.CombinedOutput(); err != nil {
fmt.Println(err)
return
}
//打印子进程的输出
fmt.Println(string(output))
}
goroutine执行linux命令,睡了2秒。而main睡一秒就杀死了bash,输出结果为:signal: killed:
package main
import (
"context"
"fmt"
"os/exec"
"time"
)
type result struct {
err error
output []byte
}
func main() {
//执行一个cmd,让它在一个协程里执行,让它执行2秒
//1秒的时候,我们杀死cmd
var (
ctx context.Context
cancelFunc context.CancelFunc
cmd *exec.Cmd
resultChan chan *result
res *result
)
//创建一个结果队列
resultChan = make(chan *result, 1000)
//context里有个channel,返回一个cancelFunc来关掉channel
//context.上下文继承了context.TODO()上下文
ctx,cancelFunc = context.WithCancel(context.TODO())
go func() {
var (
output []byte
err error
)
//exec.Command()是没办法被取消的
cmd = exec.CommandContext(ctx,"/bin/bash", "-c", "sleep 2;echo hello;") //里面有个select{case <- ctx.Done()},一旦检测到调用了cancelFunc,则kill掉bash程序(kill pid,进程id,杀死子进程)
//执行任务,捕获输出
output, err = cmd.CombinedOutput()
//把任务输出结果传给main协程
resultChan <- &result{
err: err,
output: output,
}
}()
//继续往下走
time.Sleep(1 * time.Second)
//取消上下文
cancelFunc()
//在main协程里, 等待子协程的退出,并打印任务执行结果
res = <- resultChan
// 打印任务执行结果
fmt.Println(res.err, string(res.output))
}
标签:[] 子进程 协程 cas pid ann goroutine 命令 上下文
原文地址:https://blog.51cto.com/5660061/2381502