所有的Goroutine都睡着了-死锁!---错误

所有的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)

我想写三个并发go例程,它们相互发送整数。现在,我的代码已正确编译,但在第一次执行后,它会给出错误“所有goroutines都处于休眠状态-死锁!”。我试图找到错误,但在代码逻辑中找不到任何错误。有人能帮我找到代码中的错误吗。我的代码如下。提前谢谢

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 )