gpt4 book ai didi

go - 试图避免 goroutine 泄漏时出现 panic

转载 作者:IT王子 更新时间:2023-10-29 02:02:03 25 4
gpt4 key购买 nike

我正在生成一些 goroutine 并想给它们一个 channel 来发回错误。在父 goroutine 中,我选择第一个错误并返回它,或者 wg.Done() 条件,它与关闭 done 同步> channel 。

延迟关闭 errc 以避免 goroutine 泄漏;但它会导致竞争条件。

package main

import (
"log"
"sync"
"time"
)

func f(ch chan<- bool, wg *sync.WaitGroup) {
defer wg.Done()

time.Sleep(1 * time.Second)
log.Println("f sending a value")
ch <- true
log.Println("f sent a value")
}

func g(ch chan<- bool, wg *sync.WaitGroup) {
defer wg.Done()

time.Sleep(2 * time.Second)
log.Println("g sending a value")
ch <- true
log.Println("g sent a value")
}

func main() {
var wg sync.WaitGroup

ch := make(chan bool)
bufc := make(chan bool, 2)

defer func() {
log.Println("Closing bufc")
close(bufc)
log.Println("Closed bufc")
time.Sleep(5 * time.Second)
}()

wg.Add(2)
go f(bufc, &wg)
go g(bufc, &wg)
go func() {
wg.Wait()
close(ch)
}()

select {
case done, ok := <-bufc:
log.Printf("bufc closed: %v %v", done, ok)
case <-ch:
log.Println("ch was closed")
}
}

结果:

❗ ~/c/scrap
(i) go run test.go
2018/05/01 20:28:03 f sending a value
2018/05/01 20:28:03 f sent a value
2018/05/01 20:28:03 bufc closed: true true
2018/05/01 20:28:03 Closing bufc
2018/05/01 20:28:03 Closed bufc
2018/05/01 20:28:04 g sending a value
panic: send on closed channel

goroutine 19 [running]:
main.g(0xc42009c000, 0xc42008a010)
/Users/yangmillstheory/code/scrap/test.go:23 +0xb2
created by main.main
/Users/yangmillstheory/code/scrap/test.go:42 +0x11e
exit status 2

有什么方法可以在不引起 panic 的情况下正确清理 errc channel ?我什至需要关闭 errc 吗?鉴于它已被缓冲,该 channel 上的发件人不会阻塞,所以我猜答案是否定的?

最佳答案

你的错误很明显—— channel bufc(我假设你称之为 errc)在 g 可以发送之前关闭它的值是因为 select 语句只从 bufc 接收一次并且它被 defer 关闭。您不必延迟 bufc 的关闭,而是必须进行一些同步,可能使用 sync.WaitGroup 来确保在关闭它之前发送所有值,例如只需将 close(bufc) 移动到 wg.Wait() 之后:

go func() {
wg.Wait()
close(ch)
close(bufc)
}()

在你的情况下,因为 bufc 被缓冲了,你不必关闭它,因为它不会在接收端阻塞,但是一旦你有两个以上的 goroutines 发送,你仍然需要关闭它发出正确的信号。

关于go - 试图避免 goroutine 泄漏时出现 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50126750/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com