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 中有一个recvqsendq 双链表来记录被阻塞的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):应用程序有啥方法可以要求操作系统阻止该应用程序中的设备?

React 阻止事件冒泡

confirm对话框取消后阻止ajax操作ajax做批量删除

confirm对话框取消后阻止ajax操作ajax做批量删除

Java volatile 是不是会阻止缓存或强制执行直写缓存?