gpt4 book ai didi

go - 写入永远被阻塞的 channel

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

我陷入了一种奇怪的情况,即对 channel 的写操作从未发生过。

package main

import (
"fmt"
"time"
)

func main() {
c := make(chan int)
s := make(chan bool)
k := make(chan bool)
fmt.Println("start")
go func() {
fmt.Println("routine 1")
s <- true
}()
go func() {
fmt.Println("routine 2")
for {
select {
case <-s :
for i := 0; i < 3; i++ {
fmt.Println("before")
c <- i
fmt.Println("after")
}
case <- k :
fmt.Println("k ready")
break
}
}
}()

go func() {
fmt.Println("routine 3")
for {
select {
case x := <- c :
fmt.Println("x=", x)
k <- true
fmt.Println("k done")

}
}
}()

time.Sleep(1000 * time.Millisecond)
}

这是输出:

start
routine 1
routine 2
before
routine 3
x= 0
after
before

我想知道为什么写入 channel k 会阻塞,但从未打印日志语句 fmt.Println("k ready")

这是我的想法:

  • go 例程 1 将 true 写入 channel s
  • go 例程 2 写入 0 到 channel c 并等待,因为缓冲区大小为 0,它将无法写'1'除非有人读 channel c
  • go routine 3 进入图片,读取 channel c(现在 go routine 2go 例程 2 恢复后可以写入 c) 打印 x 的值。 现在应该可以写入 channel K,但没有发生

根据我的说法,它应该能够写入 channel k 然后 goroutine 的情况 2 应该执行并打印“k ready”

谁能解释一下为什么写入被阻止的 channel ?作为修复,我知道我可以增加 channel c 的缓冲区大小,所有内容都会被打印出来,但我对修复此问题不感兴趣,相反我想了解这种情况。

一个不错的blog理解上述案例。

最佳答案

你有一个死锁。

  • goroutine 1 写入 s 然后退出
  • goroutine 2 从s读取,写入c
  • goroutine 3 从 c 读取,并写入 k,这会阻塞,因为没有从 k 读取,因为 goroutine 2 被阻塞在上面的 k 中写入。
  • goroutine 2 再次写入 c 阻塞,因为 goroutine 3 仍在尝试写入 k 因此没有从 c 读取/li>

与您所说的相反,您的缓冲区大小不是 1。您的缓冲区大小为零(即无缓冲 channel ),因此写入将阻塞,直到有内容读取。这可能是你误解的根源。根据 language specification :

A new, initialized channel value can be made using the built-in function make, which takes the channel type and an optional capacity as arguments:

make(chan int, 100)

The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.

关于go - 写入永远被阻塞的 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41782133/

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