gpt4 book ai didi

go - 带有 select 语句的程序在 go 中逃脱死锁

转载 作者:行者123 更新时间:2023-12-01 22:40:26 26 4
gpt4 key购买 nike

这个问题很可能已经被我找不到了,所以我们开始吧:

我有这个 go 函数,它使用 select 语句发送或接收“消息”,无论哪个可用:

func Seek(name string, match chan string) {
select {
case peer := <-match:
fmt.Printf("%s sent a message to %s.\n", peer, name)
case match <- name:
// Wait for someone to receive my message.

我在 4 个不同的 go-routines 上启动这个函数,使用一个无缓冲的 channel (使用缓冲区 och 1 会更好,但这只是实验性的):
people := []string{"Anna", "Bob", "Cody", "Dave"}
match := make(chan string)
for _, name := range people {
go Seek(name, match, wg)

现在,我刚刚开始使用 go 并认为由于我们使用的是无缓冲 channel ,因此“select”的发送和接收语句都应该阻塞(没有人在等待发送消息,所以你无法接收,并且没有人等待接收,因此您无法发送),这意味着函数之间不会进行任何通信,也就是死锁。但是运行代码告诉我们情况并非如此:
API server listening at: 127.0.0.1:48731
Dave sent a message to Cody.
Anna sent a message to Bob.
Process exiting with code: 0

我对你们可爱的人的问题是为什么会发生这种情况?编译器是否意识到函数想要在同一个 channel 中读/写并安排它发生?或者“选择”语句是否不断检查是否有任何人可以使用该 channel ?

对不起,如果这个问题很难回答,我还是个新手,对幕后的事情没有那么有经验:)

最佳答案

Now, I've just started using go and thought that since we're using an unbuffered channel, both the send and recieve statement of the "select" should block (there's no one waiting to send a message so you can't recieve, and there's no one waiting to recieve so you can't send)



这实际上是不正确的;实际上,有多个 goroutine 等待接收和多个 goroutine 等待发送。当一个 goroutine 执行 select像你的:
select {
case peer := <-match:
fmt.Printf("%s sent a message to %s.\n", peer, name)
case match <- name:
// Wait for someone to receive my message.

它同时等待发送和接收。由于您有多个例程执行此操作,因此每个例程都会找到发送者和接收者。什么都不会阻挡。 selects会选择 case s 是随机的,因为多个案例同时被解除阻塞。

关于go - 带有 select 语句的程序在 go 中逃脱死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60993784/

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