戈朗所有的戈都睡着了——陷入僵局



我在运行follow-golang代码段时出错。我认为进展将在wg受阻。等待((,直到go例程结束。则该值将从c1获得。但它可能不会按预期进行。

func main() {
c1 := make(chan string)
//var c1 chan string
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("go routine beginn")
time.Sleep(1 * time.Second)
c1 <- "one"
fmt.Printf("go routine donen")
}()
wg.Wait()
fmt.Printf("done c1: %vn", <-c1)
fmt.Printf("outn")
}

错误信息是,

go routine begin
fatal error: all goroutines are asleep - deadlock!

c1的写入永远不会执行,因为对c1的读取在wg.Wait()之后,而在写入c1之前,读取将停止。因此,主goroutine在wg.Wait()处等待,嵌套goroutine则在c1处等待写入。

您可以使通道缓冲,或者在单独的goroutine上等待c1读取。

在Golang中,未缓冲通道上的写入操作被阻塞。从文档中可以清楚地看到。

您的执行在被阻止

c1 <- "one"

递延报表

defer wg.Done()

从不执行。

在您的代码中,您使用的是一个无缓冲通道,它会阻塞,直到接收器接收到"一"为止。在这种情况下,代码不会经过wg。等待((,因为wg。Done((永远不会被执行。

我想这就是你想要的。

func main() {
c1 := make(chan string)
//var c1 chan string
go func() {
fmt.Printf("go routine beginn")
time.Sleep(1 * time.Second)
c1 <- "one"
fmt.Printf("go routine donen")
}()
fmt.Printf("done c1: %vn", <-c1)
fmt.Printf("outn")
}

最新更新