不知道为什么这是golang的死锁?

时间:2017-02-07 10:33:02

标签: go

我是新来的Go不确定为什么这是死锁?我想不断地从doSomething读取结果并将其存储在函数读取中而不使用for循环

func doSomething(c chan<- string){ // recursive function does something
    c <- result 
    return dosomething(c)  }

func reads(c <-chan string){
    results := ""   
    temp := <-c         
    results = results + "\n" + temp      
    return results
}

func main(){     
    go reads(c)
    doSomething(c)
}

2 个答案:

答案 0 :(得分:1)

主要gorouting正试图多次写入foo函数中的频道。 foo函数只读取一次通道。因此,写操作将等待,直到某个其他方从通道读取。当主要的goroutine被阻止时,这将陷入僵局。

如果阻塞操作不在主goroutine中,则程序将在Go程序结束时完成,只要主goroutine结束。如果主要功能可以结束,就没有死锁。

答案 1 :(得分:1)

您正试图从空频道阅读,因为reads同时执行且doSomething没有。可以通过几种方式解决问题。注意,它不是关于正确的架构或有效的方法。下面的例子解决了'#34;死锁&#34;原始代码段的问题,而不是更多。

同时读写:

package main

func doSomething(c chan<- string) { // recursive function does something
    c <- "result"
    doSomething(c)
}

func reads(c <-chan string) {
    results := <-c
    fmt.Println("Boo", results)
}

func main() {
    c := make(chan string)
    go reads(c)
    go doSomething(c) // Write concurrentely
}

使用select处理频道阅读操作:

func reads(c <-chan string) {
    // Use select
    select {
    case res := <-c:
        fmt.Println("received message", res)
    default:
        fmt.Println("no results received")
    }
}

我宁愿选择第一种和第二种方法的组合。

写完后阅读(远离正确的设计):

func main() {
    c := make(chan string)

    go doSomething(c)
    reads(c) // Read after write
}