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

时间:2009-11-13 17:24:29

标签: go signals-slots goroutine

到目前为止,我看到的所有示例都涉及阻止获取结果(通过<-chan运算符)。

我目前的方法是将指针传递给结构:

type goresult struct {
    result resultType;
    finished bool;
}
完成时goroutine写的

。然后,只要方便,就可以轻松检查finished。你有更好的选择吗?

我真正的目标是Qt风格的信号槽系统。我有一个预感,解决方案看起来几乎是微不足道的(chan很多未探索的潜力),但我还不熟悉该语言来解决这个问题。

3 个答案:

答案 0 :(得分:13)

您可以使用“逗号,确定”模式(请参阅“effective go”上的页面):

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

答案 1 :(得分:5)

Select statements允许您一次检查多个频道,采用随机分支(通信正在等待的分支):

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
    }
    }
}
  

对于所有发送和接收   “select”语句中的表达式,   评估通道表达式,   以及出现的任何表达式   在发送的右侧   表达式,按从上到下的顺序排列。   如果任何结果操作可以   继续,选择一个和   相应的沟通和   陈述被评估。除此以外,   如果有默认情况,那   执行;如果没有,声明会阻止   直到其中一个通讯可以   完整。

答案 2 :(得分:4)

您还可以使用len:

查看通道缓冲区以查看它是否包含任何内容
if len(channel) > 0 {
  // has data to receive
}

这不会触及频道缓冲区,与foo, gotValue := <- ch不同,后者在gotValue == true时删除了一个值。