chan中可以阻塞多少写操作

How many write operation can be blocked in chan

我使用 chan 作为 goroutines 到 write/read,如果 chan 已满,写入 goroutines 将被阻塞,直到另一个 goroutine 从 chan 读取。

我知道chan中有一个recvqsendq双链表来记录阻塞的goroutines。我的问题是,如果 chan 未被读取,总共可以阻止多少 goroutines?这取决于内存大小吗?

是的,这取决于内存。这取决于文档中提到的通道长度,一旦通道已满,缓冲通道就会被阻塞,而当另一个值被添加到通道时,缓冲通道就会被解除阻塞。 channels

来自文档的代码片段:

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 处理程序正在执行进程,任何更多处理程序将阻止尝试发送到已填充的通道缓冲区,直到现有处理程序之一完成并从缓冲区接收。

TLDR: 只要您的应用程序可以装入内存并且可以运行,通道等待队列就不会有任何问题。

语言规范不限制通道等待 goroutine 的数量,因此没有实际限制。

运行time 实现可能会将等待的 goroutines 限制为一个微不足道的高值(例如,由于指针大小、整数计数器大小等),但要达到这样的实现限制,你会 运行 很快就会内存不足。

Goroutines 是轻量级线程,但它们确实需要很小的内存。它们从一个大约 KB 的小堆栈开始,所以即使你估计它是 1 KB,如果你有一百万个 goroutine,那至少已经是 1 GB 内存,如果你有十亿个 goroutine,那就是 1 TB。例如,十亿远不及 int64 的最大值。

您的 CPU 和 Go 运行 时间在 运行 进入实现特定的等待队列限制之前管理数十亿个 goroutine 会遇到麻烦。

My question is how many goroutines totally can be blocked if chan is not read?

全部。