【发布时间】:2021-12-31 07:17:58
【问题描述】:
我正在尝试理解 Go 中的上下文和通道,但我无法理解正在发生的事情。这是一些示例代码。
package main
import (
"context"
"fmt"
"log"
"time"
"golang.org/x/time/rate"
)
func main() {
msgs := make(chan string)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
limiter := rate.NewLimiter(rate.Every(2*time.Second), 1)
go func(ctx context.Context, limiter *rate.Limiter) {
for {
limiter.Wait(context.Background())
select {
case <-ctx.Done():
log.Printf("finished!")
return
case msg := <-msgs:
log.Printf("receiving a message: %s", msg)
}
}
}(ctx, limiter)
defer close(msgs)
i := 0
for {
msgs <- fmt.Sprintf("sending message %d", i)
i++
if i > 10 {
break
}
}
}
我得到的结果是不确定的。有时记录器会打印出三条消息,有时是五条。另外,程序每次都以死锁结束:
2021/12/31 02:07:21 receiving a message: sending message 0
2021/12/31 02:07:23 receiving a message: sending message 1
2021/12/31 02:07:25 receiving a message: sending message 2
2021/12/31 02:07:27 receiving a message: sending message 3
2021/12/31 02:07:29 receiving a message: sending message 4
2021/12/31 02:07:29 finished!
fatal error: all goroutines are asleep - deadlock!
所以,我想我有几个问题:
- 为什么我的 goroutine 没有在一秒钟后结束?
- 为什么会出现死锁?如何避免这种性质的死锁?
【问题讨论】:
标签: go deadlock channel goroutine