考虑这个功能:
func doAllWork() error {
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 2; i++ {
go func() {
defer wg.Done()
for j := 0; j < 10; j++ {
result, err := work(j)
if err != nil {
// can't use `return err` here
// what sould I put instead ?
os.Exit(0)
}
}
}()
}
wg.Wait()
return nil
}
Run Code Online (Sandbox Code Playgroud)
在每个goroutine中,该函数work()
被调用10次.如果一个调用work()
在任何正在运行的goroutine中返回错误,我希望所有goroutine立即停止,并退出程序.可以os.Exit()
在这里使用吗?我该怎么处理?
编辑:这个问题不同于如何停止goroutine,因为我需要关闭所有goroutine如果一个错误发生
我试图阻止一个例行公事,但我找不到实现这个目标的方法.我正在考虑使用第二个频道,但是如果我从中读取它会阻止它不是吗?这是一些代码,我希望解释我正在尝试做什么.
package main
import "fmt"
import "time"
func main() {
var tooLate bool
proCh := make(chan string)
go func() {
for {
fmt.Println("working")
//if is tooLate we stop/return it
if tooLate {
fmt.Println("stopped")
return
}
//processing some data and send the result on proCh
time.Sleep(2 * time.Second)
proCh <- "processed"
fmt.Println("done here")
}
}()
select {
case proc := <-proCh:
fmt.Println(proc)
case <-time.After(1 * time.Second):
// somehow send tooLate <- true
//so that we can stop the go routine running …
Run Code Online (Sandbox Code Playgroud) 我用goroutines做了一个简单的时钟信号:
func clockloop(ch chan byte) {
count := 0
for {
time.Sleep(FRAMELEN)
count++
innerfor:
for count {
select {
case ch <- 1:
count--
default:
break innerfor
}
}
}
}
func MakeClock() chan byte {
clock := make(chan byte)
go clockloop(clock)
return clock
}
Run Code Online (Sandbox Code Playgroud)
我知道这个时钟是不精确的,但这是无关紧要的.我想知道的是阻止这个goroutine的最佳方法是什么?
理想情况下,我希望它能在通道的任何听众超出范围时立即停止,但我知道如何做到这一点(很像垃圾收集器,但对于goroutines).我想出了两种手动停止它的方法:(1)使用全局停止变量,所有这些goroutine都会检查每个循环,(2)使用停止通道.这些中的每一个的缺点是我必须手动停止goroutines.
我正在尝试通过Go 程序中的SSH 包运行脚本(到目前为止我已经成功了)。
我的问题是,如果用户具有 sudo 权限,脚本会尝试使用 sudo 运行命令,这会导致 bash 脚本暂停,直到用户输入密码。
例如:
[ERROR ] Install cs-server: Checking dependencies: missing: lib32gcc1
# It attempts to install the missing dependencies with sudo but pauses here
[sudo] password for guest:
Run Code Online (Sandbox Code Playgroud)
在我的 Go 程序中,我写了一些类似的东西:
// Connect to SSH and retreive session...
out, err := session.StdoutPipe()
if err != nil {
log.Fatal(err)
}
go func(out io.Reader) {
r := bufio.NewScanner(out)
for r.Scan() {
fmt.Println(r.Text())
}
}(out)
// Execute ssh command...
Run Code Online (Sandbox Code Playgroud)
我收到与上面示例完全相同的输出,仅在这种情况下,我什至看不到该行[sudo] password for …
我有一个类似于How to stop a goroutine with a small twist的问题。我不确定 goroutine 是否正在运行。
var quit = make(chan bool)
func f1() {
go func() {
t := time.NewTimer(time.Minute)
select {
case <-t.C:
// Do stuff
case <-quit:
return
}
}()
}
func f2() {
quit <- true
}
Run Code Online (Sandbox Code Playgroud)
如果f2()
在 之后不到一分钟被调用f1()
,则 goroutine 返回。但是,如果它在一分钟后被调用,goroutine 将已经返回并f2()
会阻塞。f2()
如果 goroutine 正在运行,我想取消它,否则什么都不做。
我在这里试图实现的是当且仅当它在创建后的一分钟内没有被取消时才执行任务。
说明:
f2()
被多次调用的。f1()
将确保每分钟调用它的次数不会超过一次。在我的程序中,我有几个 go-routines,它们本质上是在运行无休止的进程。为什么?你可能会问,长话短说这是我整个申请的目的,所以改变它是不可能的。我想让用户能够停止单个 go-routine。我知道我可以使用 channel 来通知 go-routines 停止,但是在某些情况下,我可能有 10 个 go-routines 正在运行而我只想停止 1。问题是 go-routines 的数量我想运行的是动态的并基于用户输入。对我来说,添加动态停止 go-routine 并允许单打停止而没有其他功能的最佳方法是什么?
有没有办法检测 go 例程在执行时是否被中断?我想要类似于InterruptedException
Java的东西: https ://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html