【问题标题】:How do I find out if a goroutine is done, without blocking?如何在不阻塞的情况下确定 goroutine 是否已完成?
【发布时间】:2010-12-16 09:17:55
【问题描述】:

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

我当前的方法涉及将指针传递给结构:

type goresult struct {
    result resultType;
    finished bool;
}

goroutine 在完成时写入的内容。然后在方便的时候检查finished 就很简单了。你有更好的选择吗?

我真正的目标是 Qt 风格的信号槽系统。我有一种预感,这个解决方案看起来几乎是微不足道的(chans 有 很多 未开发的潜力),但我对语言还不够熟悉,无法弄清楚。

【问题讨论】:

    标签: go signals-slots goroutine


    【解决方案1】:

    您可以使用“逗号,ok”模式(参见他们的页面“effective go”):

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

    【讨论】:

    • 你必须写:select { case foo :=
    【解决方案2】:

    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”语句中的表达式, 评估通道表达式, 以及出现的任何表达式 在发送的右侧 表达式,按从上到下的顺序。 如果任何结果操作可以 继续,一个被选中并且 相应的沟通和 语句被评估。否则, 如果有默认情况,那 执行;如果不是,语句块 直到其中一个通讯可以 完成。

    【讨论】:

    • @Jurily:你确定吗?它应该是正确的,但如果没有&lt;- 后面的空格会更好看。
    【解决方案3】:

    您还可以使用 len 查看通道缓冲区以查看它是否包含任何内容:

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

    这不会触及通道缓冲区,不像foo, gotValue := &lt;- chgotValue == true 时删除一个值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      • 2015-12-07
      • 2020-06-12
      相关资源
      最近更新 更多