抛出:所有的goroutine都处于休眠状态 – 死锁

huangapple go评论96阅读模式
英文:

throw: all goroutines are asleep - deadlock

问题

给定以下简单的Go程序

package main

import (
    "fmt"
)

func total(ch chan int) {
    res := 0
    for iter := range ch {
        res += iter
    }
    ch <- res
}

func main() {
    ch := make(chan int)
    go total(ch)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println("Total is ", <-ch)
}

我想知道为什么会出现以下错误信息

throw: all goroutines are asleep - deadlock!

谢谢

英文:

Given the following simple Go program

package main

import (
	&quot;fmt&quot;
)

func total(ch chan int) {
	res := 0
	for iter := range ch {
		res += iter
	}
	ch &lt;- res
}

func main() {
	ch := make(chan int)
	go total(ch)
	ch &lt;- 1
	ch &lt;- 2
	ch &lt;- 3
	fmt.Println(&quot;Total is &quot;, &lt;-ch)
}

I am wondering if someone can enlighten me as to why I get

throw: all goroutines are asleep - deadlock!

thank you

答案1

得分: 34

由于您从未关闭ch通道,因此范围循环将永远不会结束。

您不能在同一个通道上发送结果。解决方案是使用另一个通道。

您的程序可以像这样进行调整:

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // 发送结果
}

func main() {
    ch := make(chan int)
    rch  := make(chan int)
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close (ch) // 这将结束total函数中的循环
    result := <- rch // 等待total给出结果
    fmt.Println("总和为", result)
}
英文:

As you never close the ch channel, the range loop will never finish.

You can't send back the result on the same channel. A solution is to use a different one.

Your program could be adapted like this :

package main

import (
    &quot;fmt&quot;
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out &lt;- res // sends back the result
}

func main() {
    ch := make(chan int)
    rch  := make(chan int)
    go total(ch, rch)
    ch &lt;- 1
    ch &lt;- 2
    ch &lt;- 3
    close (ch) // this will end the loop in the total function
    result := &lt;- rch // waits for total to give the result
    fmt.Println(&quot;Total is &quot;, result)
}

答案2

得分: -3

这也是正确的。

package main

import "fmt"

func main() {
    c := make(chan int)
    go do(c)
    c <- 1
    c <- 2
    // close(c)
    fmt.Println("Total is ", <-c)
}

func do(c chan int) {
    res := 0
    // for v := range c {
    //  res = res + v
    // }
    for i := 0; i < 2; i++ {
        res += <-c
    }
    c <- res
    fmt.Println("something")
}
英文:

This is also right.

package main

import &quot;fmt&quot;

func main() {
	c := make(chan int)
	go do(c)
	c &lt;- 1
	c &lt;- 2
	// close(c)
	fmt.Println(&quot;Total is &quot;, &lt;-c)
}

func do(c chan int) {
	res := 0
	// for v := range c {
	// 	res = res + v
	// }
	for i := 0; i &lt; 2; i++ {
		res += &lt;-c
	}
	c &lt;- res
	fmt.Println(&quot;something&quot;)
}

huangapple
  • 本文由 发表于 2012年9月13日 09:51:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/12398359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定