我是Golang的新手,正在尝试一些典型的使用通道的生产者消费者。我知道生产者和消费者都应该写入和读取相同的通道。但只是为了实验,我让他们写入和读取不同的通道,如下所示
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
fmt.Println("Starting the main application")
channel :=make( chan int)
channel1 :=make( chan int)
go generateNumbersV2(&wg, channel)
go printNumbersV2(&wg, channel1)
fmt.Println("Waiting for other goroutines")
wg.Wait()
//close()
//close(channel)
fmt.Println("All goroutines finished")
}
func printNumbersV2(wg *sync.WaitGroup, rc <-chan int) {
defer wg.Done()
for idx:=0 ;idx<3;idx++ {
val := <-rc
fmt.Println("******value received from channel ",val)
}
}
func generateNumbersV2(wg *sync.WaitGroup, wc chan<- int) {
defer wg.Done()
for idx:=0 ;idx<3;idx++ {
wc<-idx
fmt.Println("###value written to channel ",idx)
}
}
字符串
当我运行程序时,我得到下面的错误。
fatal error: all goroutines are asleep - deadlock!
型
现在,虽然我知道两个goroutine都被阻塞了,一个在对channel 1的读调用上,另一个在对channel 1的写调用上,所以程序永远不会终止。但我的问题是,如果实际上我在等待这些通道中的值,程序不应该无限期地等待,而不是将其声明为死锁。如果稍后,由于一些网络读/写,这些值到达,并且一些其它的Go例程写入这些通道。
2条答案
按热度按时间lokaqttq1#
只有当所有的goroutine都在同步原语上被阻塞时,一个正在运行的程序才会因为死锁而终止。如果所有的goroutine都被阻塞,等待通道操作和/或互斥锁,那么就不会有网络接收,因为没有goroutine在监听网络连接。这也意味着,在一个有很多goroutine的程序中,你可能有很多死锁的goroutine组,但是程序会继续运行。因为还有其他的goroutine可以继续前进。
9cbw7uwe2#
generateNumbersV2
正在向channel
发送数据-但Go未检测到接收器。printNumbersV2
正在等待从channel1
接收数据-但Go未检测到生产者。程序将等待可能在某个时刻到达的数据,例如网络请求,这是正确的。如果您创建这样一个函数,死锁错误将消失。
一个简单的解决方案,用于说明目的:
字符串