英文:
How do I find out if a goroutine is done, without blocking?
问题
到目前为止,我看到的所有示例都涉及阻塞以获取结果(通过<-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 (chan
s have <i>lots</i> of unexplored potential), but I'm not yet familiar enough with the language to figure it out.
答案1
得分: 14
你可以使用“逗号,ok”模式(参见他们在“effective go”页面上的说明):
foo := <- ch; // 这会阻塞。
foo, ok := <- ch; // 这会立即返回。
英文:
You can use the "comma, ok" pattern (see their page on "effective go"):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
答案2
得分: 6
选择语句允许您一次检查多个通道,选择一个随机分支(其中有等待通信的分支):
func main() {
for {
select {
case w := <-workchan:
go do_work(w)
case <-signalchan:
return
// 如果没有可用的通信,则在此处执行默认操作
default:
// 执行空闲工作
}
}
}
对于“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.
答案3
得分: 5
你还可以通过使用len来查看通道缓冲区是否包含任何内容:
if len(channel) > 0 {
// 有数据可接收
}
这不会触及通道缓冲区,不像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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论