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

发布于 2024-08-11 16:35:34 字数 365 浏览 10 评论 0原文

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

我当前的方法涉及传递一个指向结构的指针:

type goresult struct {
    result resultType;
    finished bool;
}

goroutine 在完成时写入该结构。然后只要方便就可以简单地检查finished。你有更好的选择吗?

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

All the examples I've seen so far involve blocking to get the result (via the <-chan operator).

My current approach involves passing a pointer to a struct:

type goresult struct {
    result resultType;
    finished bool;
}

which the goroutine writes upon completion. Then it's a simple matter of checking finished whenever convenient. Do you have better alternatives?

What I'm really aiming for is a Qt-style signal-slot system. I have a hunch the solution will look almost trivial (chans have lots of unexplored potential), but I'm not yet familiar enough with the language to figure it out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

始于初秋 2024-08-18 16:35:34

您可以使用“comma, ok”模式(请参阅他们的页面“ effective go”):

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

You can use the "comma, ok" pattern (see their page on "effective go"):

foo     := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
他夏了夏天 2024-08-18 16:35:34

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

Select statements allows you to check multiple channels at once, taking a random branch (of the ones where communication is waiting):

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

空城缀染半城烟沙 2024-08-18 16:35:34

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

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

这不会触及通道缓冲区,与 foo,gotValue := <- ch 不同,它会在 < 时删除值代码>gotValue == true。

You can also peek at the channel buffer to see if it contains anything by using 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文