chan中可以阻止多少写操作
Posted
技术标签:
【中文标题】chan中可以阻止多少写操作【英文标题】:How many write operation can be blocked in chan 【发布时间】:2021-12-01 18:41:26 【问题描述】:我使用chan
用于goroutines 进行写入/读取,如果chan
已满,写入goroutines 将被阻塞,直到另一个goroutine 从chan
读取。
我知道chan
中有一个recvq
和sendq
双链表来记录被阻塞的goroutine。我的问题是,如果不读取 chan
,总共可以阻止多少个 goroutine?这是否取决于内存大小?
【问题讨论】:
请写一个描述性的答案,详细说明你想谈什么 【参考方案1】:TLDR:只要您的应用可以放入内存并可以运行,您就不会有任何频道等待队列问题。
语言规范不限制通道等待的 goroutine 数量,因此没有实际限制。
运行时实现可能会将等待的 goroutine 限制为一个微不足道的高值(例如,由于指针大小、整数计数器大小等),但要达到这样的实现限制,您将很快耗尽内存。
Goroutine 是轻量级线程,但它们确实需要很小的内存。它们从大约 1 KB 的小堆栈开始,因此即使您估计它为 1 KB,如果您有 100 万个 goroutine,那至少已经是 1 GB 内存,如果您有 10 亿个 goroutine,那就是 1 TB。例如,10 亿远不及 int64
的最大值。
在遇到特定于实现的等待队列限制之前,您的 CPU 和 Go 运行时将难以管理数十亿个 goroutine。
【讨论】:
【参考方案2】:是的,这取决于内存。它取决于文档中提到的通道的 len,一旦通道已满,缓冲通道就会被阻塞,而当另一个值被添加到通道时,它就会被解除阻塞。 channels
来自文档的代码 sn-p:
var sem = make(chan int, MaxOutstanding)
func handle(r *Request)
sem <- 1 // Wait for active queue to drain.
process(r) // May take a long time.
<-sem // Done; enable next request to run.
func Serve(queue chan *Request)
for
req := <-queue
go handle(req) // Don't wait for handle to finish.
一旦 MaxOutstanding 处理程序正在执行进程,任何其他处理程序都会阻止尝试发送到已填充的通道缓冲区,直到现有处理程序之一完成并从缓冲区接收。
【讨论】:
【参考方案3】:我的问题是,如果不读取 chan,总共可以阻止多少个 goroutine?
所有的。
【讨论】:
以上是关于chan中可以阻止多少写操作的主要内容,如果未能解决你的问题,请参考以下文章
iOS(Apple):应用程序有啥方法可以要求操作系统阻止该应用程序中的设备?
confirm对话框取消后阻止ajax操作ajax做批量删除