From c689440320e2b71227f989b8c5b391d061688dc5 Mon Sep 17 00:00:00 2001 From: Acaibrid <95097635+A-caibird@users.noreply.github.com> Date: Thu, 8 Feb 2024 07:43:12 +0800 Subject: [PATCH] Update ch8-05.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更详细的描述携程泄漏 --- ch8/ch8-05.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ch8/ch8-05.md b/ch8/ch8-05.md index b7d572a..dbf147a 100644 --- a/ch8/ch8-05.md +++ b/ch8/ch8-05.md @@ -98,7 +98,8 @@ func makeThumbnails4(filenames []string) error { } ``` -这个程序有一个微妙的bug。当它遇到第一个非nil的error时会直接将error返回到调用方,使得没有一个goroutine去排空errors channel。这样剩下的worker goroutine在向这个channel中发送值时,都会永远地阻塞下去,并且永远都不会退出。这种情况叫做goroutine泄露(§8.4.4),可能会导致整个程序卡住或者跑出out of memory的错误。 +这个程序有一个微妙的bug。在 makeThumbnails4 函数中,它使用了一个 errors 通道来收集每个协程的错误。然后,在 for range filenames 循环中,它从 errors 通道接收错误,并在遇到非空错误时立即返回该错误。 +然而,如果其中一个协程在处理过程中发生了错误,导致向 errors 通道发送了错误,但其他协程仍在继续处理。由于没有其他协程接收这些错误,这些协程将一直阻塞在 errors <- err 的发送操作上,无法退出。这就是协程泄漏的问题。 最简单的解决办法就是用一个具有合适大小的buffered channel,这样这些worker goroutine向channel中发送错误时就不会被阻塞。(一个可选的解决办法是创建一个另外的goroutine,当main goroutine返回第一个错误的同时去排空channel。)