Vog*_*guo -2 channel go goroutine
以下代码记录了一个错误:
致命错误:所有goroutine都在睡着-死锁!
package main
import "fmt"
func main() {
ch := make(chan int)
ch <- 1
fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)
但是,当我将代码更改为:
package main
import "fmt"
func assign (ch chan int) {
ch <- 1
}
func main() {
ch := make(chan int)
go assign (ch)
fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)
打印出“ 1”。
然后我使用了缓冲通道:
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)
也可以打印“ 1”和“ 2”。
我对此情况有些困惑。提前致谢!
僵局发生的原因:
在第一个代码段中,您只有一个主要的goroutine,当您尝试在此处写入通道时,它会被阻塞:
ch <- 1
Run Code Online (Sandbox Code Playgroud)
因为没有人从通道读取数据,所以主goroutine正在等待继续进行。
参见有效转到->渠道
如果通道未缓冲,则发送方将阻塞,直到接收方收到该值为止。
发送者是main功能,接收者也是main功能。
如何避免僵局:
为了解决这个问题,您有两种选择:
选项1:按以下方式ch缓冲通道:
ch := make(chan int, 1) // buffer length is set to 1
Run Code Online (Sandbox Code Playgroud)
从巡回演出
仅在缓冲区已满时发送到缓冲的通道块。
因此,您可以写入通道,直到缓冲区已满。然后,必须有人从该频道开始阅读。
选项2:像在第二个代码段中一样,从goroutine写入通道:
func assign(ch chan int) {
ch <- 1
}
func main() {
ch := make(chan int)
go assign(ch) // does not block the main goroutine
fmt.Println(<-ch) // waiting to read from the channel
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,main功能将一直执行到fmt.Println(<-ch)从通道读取后立即继续。
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |