gpt4 book ai didi

go - 选定组中的 channel 在指定时间内没有接收到信号时跳出循环

转载 作者:IT王子 更新时间:2023-10-29 00:57:23 25 4
gpt4 key购买 nike

当且仅当我在特定时间段内在我的 select 语句正在监听的任何 channel 上都没有收到任何信号时,我该如何跳出包含 select 语句的惯用 Go for 循环。

让我用一个例子来加强这个问题。

设置:

  1. 假设我有一个 channel var listenCh <-chan string我正在听。
  2. 让我们假设一些其他的 go 例程(不在我们的控制范围内)在此 channel 上发送不同的字符串。
  3. 我对给定的字符串进行一些处理,然后在 listenCh 上监听下一个字符串。 .

要求:

我想在 listenCh 上的两个连续信号之间最多等待 10 秒(精度不重要) ,在我关闭操作之前(永久中断 for 循环)。

代码 stub :

func doingSomething(listenCh <-chan string) {
var mystr string
for {
select {
case mystr <-listenCh:
//dosomething
case /*more than 10 seconds since last signal on listenCh*/:
return
}
}
}

我将如何以最有效的方式实现我的要求。

常用的退出 channel 技术 time.After(time.Duration)似乎在一个循环后不会重置,因此即使有连续的值流,整个程序也会在 10 秒内关闭。

我在 SO 上找到了问题的变体(但不是我想要的),但我看到的没有一个能回答我的特定用例。

最佳答案

前言:使用time.Timer是推荐的方式,这里使用time.After()只是为了演示和推理。请使用第二种方法。


使用time.After()(不推荐这样做)

如果你输入 time.After()在 case 分支中,这将在每次迭代中“重置”,因为每次都会返回一个新 channel ,这样就可以了:

func doingSomething(listenCh <-chan string) {
for {
select {
case mystr := <-listenCh:
log.Println("Received", mystr)
case <-time.After(1 * time.Second):
log.Println("Timeout")
return
}
}
}

(我在 Go Playground 上使用 1 秒超时来进行测试。)

我们可以这样测试它:

ch := make(chan string)
go func() {
for i := 0; i < 3; i++ {
ch <- fmt.Sprint(i)
time.Sleep(500 * time.Millisecond)
}
}()
doingSomething(ch)

输出(在 Go Playground 上尝试):

2009/11/10 23:00:00 Received 0
2009/11/10 23:00:00 Received 1
2009/11/10 23:00:01 Received 2
2009/11/10 23:00:02 Timeout

使用time.Timer(推荐方案)

如果从 channel 接收的速率很高,这可能有点浪费资源,因为 time.After() 创建并在底层使用了一个新的计时器,它不会如果您在超时前从 channel 收到值,当不再需要时神奇地停止并立即收集垃圾。

一个对资源更友好的解决方案是创建一个 time.Timer在循环之前,如果在超时之前收到一个值,则将其重置。

这是它的样子:

func doingSomething(listenCh <-chan string) {
d := 1 * time.Second
t := time.NewTimer(d)
for {
select {
case mystr := <-listenCh:
log.Println("Received", mystr)
if !t.Stop() {
<-t.C
}
t.Reset(d)
case <-t.C:
log.Println("Timeout")
return
}
}
}

测试和输出是一样的。在 Go Playground 上试试这个.

关于go - 选定组中的 channel 在指定时间内没有接收到信号时跳出循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53219026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com