所有的Goroutine都睡着了-死锁!---错误
我想写三个并发go例程,它们相互发送整数。现在,我的代码已正确编译,但在第一次执行后,它会给出错误“所有goroutines都处于休眠状态-死锁!”。我试图找到错误,但在代码逻辑中找不到任何错误。有人能帮我找到代码中的错误吗。我的代码如下。提前谢谢所有的Goroutine都睡着了-死锁!---错误,go,concurrent-programming,goroutine,Go,Concurrent Programming,Goroutine,我想写三个并发go例程,它们相互发送整数。现在,我的代码已正确编译,但在第一次执行后,它会给出错误“所有goroutines都处于休眠状态-死锁!”。我试图找到错误,但在代码逻辑中找不到任何错误。有人能帮我找到代码中的错误吗。我的代码如下。提前谢谢 package main import "rand" func Routine1(command12 chan int, response12 chan int, command13 chan int, response13 chan int)
package main
import "rand"
func Routine1(command12 chan int, response12 chan int, command13 chan int, response13 chan int) {
for i := 0; i < 10; i++ {
y := rand.Intn(10)
if y%2 == 0 {
command12 <- y
}
if y%2 != 0 {
command13 <- y
}
select {
case cmd1 := <-response12:
print(cmd1, " 1st\n")
case cmd2 := <-response13:
print(cmd2, " 1st\n")
}
}
close(command12)
}
func Routine2(command12 chan int, response12 chan int, command23 chan int, response23 chan int) {
for i := 0; i < 10; i++ {
select {
case x, open := <-command12:
{
if !open {
return
}
print(x, " 2nd\n")
}
case x, open := <-response23:
{
if !open {
return
}
print(x, " 2nd\n")
}
}
y := rand.Intn(10)
if y%2 == 0 {
response12 <- y
}
if y%2 != 0 {
command23 <- y
}
}
}
func Routine3(command13 chan int, response13 chan int, command23 chan int, response23 chan int) {
for i := 0; i < 10; i++ {
select {
case x, open := <-command13:
{
if !open {
return
}
print(x, " 2nd\n")
}
case x, open := <-command23:
{
if !open {
return
}
print(x, " 2nd\n")
}
}
y := rand.Intn(10)
if y%2 == 0 {
response13 <- y
}
if y%2 != 0 {
response23 <- y
}
}
}
func main() {
command12 := make(chan int)
response12 := make(chan int)
command13 := make(chan int)
response13 := make(chan int)
command23 := make(chan int)
response23 := make(chan int)
go Routine1(command12, response12, command13, response13)
go Routine2(command12, response12, command23, response23)
Routine3(command13, response13, command23, response23)
}
主程序包
输入“兰特”
func Routine1(command12 chan int,response12 chan int,command13 chan int,response13 chan int){
对于i:=0;i<10;i++{
y:=rand.Intn(10)
如果y%2==0{
命令12
这将在新的goroutine中启动Routine1,主goroutine将继续执行下一条语句。因此,Routine1和Routine2将同时执行,但Routine2完成后将启动Routine3。您可能会错过另一条“go”语句
然后,我试着按照你的计划去做。按惯例你是这样做的
command13 <- y
正如您所看到的,没有一个goroutine可以访问command13(但您将两次传递command12)。因此,Routine1、Routine2或Routine3都无法继续。死锁
我建议您回到绘图板,首先考虑您要做的事情,绘制一些关于预期消息流的图表,然后尝试实现该行为
现在很难调试你的程序因为
- 我不知道您正在尝试做什么。没有关于消息流或类似内容的详细描述。事实上,您的代码根本不包含任何文档
- 您正在将名为
response23
的通道传递给名为response13
等的参数。很容易将它们混淆
- 所有这些通用名称,如command12等,使人们很难理解这个频道应该做什么
- 在发布源代码之前,最好
gofmt
先发布源代码:)
作为起点,我可以向你推荐“素数”示例表单。在此示例中,可能的素数从一个goroutine传递到另一个goroutine。此外,此示例还包含一些关于消息流的漂亮图形以及一些非常好的解释。您可能会喜欢它。您已将通道声明为阻塞通道。只要您尝试发送或接收goroutine将从其中一个通道阻塞,直到读取该值或接收到一个值为止
例如,在Routine1
中,如果您调用command12 Hi tux21b,我会根据您的建议修改我的程序,比如添加到例程3并更改Routine3(command13,response13,command23,response23)。然而,问题仍然是一样的。实际上,我最累的事情是在两个例程之间创建两个通道,然后在它们之间发送int。例如,在例程1和3之间,通道是command13和response13。例程1使用command13发送int,response13从例程3接收int。[下一步]对于用于向例程1发送int和从例程1接收int的例程3 response13和command13(command/response13表示例程1和3之间的通道)。现在,由于这三个例程是并发的,并且它们有特定的例程来处理接收到的消息或发送消息,为什么它们会陷入死锁?将第二个go语句放在Routine2调用之前(而不是常规电话)嗨,罗博瑟,你说的是“常规电话,如果你呼叫命令12
command13 <- y
Routine2(command12, response12,command23, response23)
Routine3(command12, response12,command23, response23 )