简体   繁体   English

如何在不阻塞的情况下查明goroutine是否已完成?

[英]How do I find out if a goroutine is done, without blocking?

All the examples I've seen so far involve blocking to get the result (via the <-chan operator). 到目前为止,我看到的所有示例都涉及阻塞以获得结果(通过<-chan运算符)。

My current approach involves passing a pointer to a struct: 我当前的方法涉及将指针传递给结构:

type goresult struct {
    result resultType;
    finished bool;
}

which the goroutine writes upon completion. goroutine在完成后写的。 Then it's a simple matter of checking finished whenever convenient. 然后,只要方便,检查finished就很简单了。 Do you have better alternatives? 你有更好的选择吗?

What I'm really aiming for is a Qt-style signal-slot system. 我真正的目标是Qt风格的信号槽系统。 I have a hunch the solution will look almost trivial ( chan s have lots of unexplored potential), but I'm not yet familiar enough with the language to figure it out. 我有预感,解决方案看起来几乎是微不足道的( chan很多未探索的潜力),但我还不熟悉这种语言来解决它。

You can use the "comma, ok" pattern (see their page on " effective go "): 您可以使用“逗号,确定”模式(请参阅“ 有效去 ”页面):

foo     := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.

Select statements allows you to check multiple channels at once, taking a random branch (of the ones where communication is waiting): Select语句允许您一次检查多个通道,采用随机分支(通信正在等待的分支):

func main () {
    for {
    select {
        case w := <- workchan:
            go do_work(w)
        case <- signalchan:
            return
        // default works here if no communication is available
        default:
            // do idle work
    }
    }
}

For all the send and receive expressions in the "select" statement, the channel expressions are evaluated, along with any expressions that appear on the right hand side of send expressions, in top-to-bottom order. 对于“select”语句中的所有发送和接收表达式,将按从上到下的顺序评估通道表达式以及发送表达式右侧显示的任何表达式。 If any of the resulting operations can proceed, one is chosen and the corresponding communication and statements are evaluated. 如果任何结果操作可以继续,则选择一个并评估相应的通信和语句。 Otherwise, if there is a default case, that executes; 否则,如果存在默认情况,则执行; if not, the statement blocks until one of the communications can complete. 如果不是,则语句​​将阻塞,直到其中一个通信完成。

You can also peek at the channel buffer to see if it contains anything by using len: 您还可以使用len查看通道缓冲区以查看它是否包含任何内容:

if len(channel) > 0 {
  // has data to receive
}

This won't touch the channel buffer, unlike foo, gotValue := <- ch which removes a value when gotValue == true . 这不会触及通道缓冲区,不像foo, gotValue := <- ch ,当gotValue == true时删除一个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM