【问题标题】:golang chanel not working with sync.WaitGroupgolang 频道无法与 sync.WaitGroup 一起使用
【发布时间】:2020-09-05 18:51:59
【问题描述】:

我的代码



package main

import (
   "fmt"
   "sync"
)

func other(c chan int, wg *sync.WaitGroup) {
   c <- 455
   wg.Done()
}

func addInt(c chan int, d int, wg *sync.WaitGroup) {
   c <- d
   wg.Done()
}
func main() {

   var wg sync.WaitGroup
   myChanel := make(chan int)

   wg.Add(2)

   go addInt(myChanel, 5, &wg)
   go other(myChanel, &wg)

   wg.Wait()

   c := 0


   for v := range myChanel {
       if c == 1 {

           close(myChanel)
       }
       fmt.Println(v)
       c++

   }

}


我正在学习 golang 看地雷,但我确实遇到了这样的错误。我查看了其他来源。我无法找到健康的解决方案。我再次尝试关闭(香奈儿)。

错误输出

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0000140f8)
        /usr/lib/go-1.13/src/runtime/sema.go:56 +0x42
sync.(*WaitGroup).Wait(0xc0000140f0)
        /usr/lib/go-1.13/src/sync/waitgroup.go:130 +0x64
main.main()
        /home/zeus/go/src/github.com/awesomeProject/pool.go:27 +0xe4

goroutine 6 [chan send]:
main.addInt(0xc000016120, 0x5, 0xc0000140f0)
        /home/zeus/go/src/github.com/awesomeProject/pool.go:14 +0x3f
created by main.main
        /home/zeus/go/src/github.com/awesomeProject/pool.go:24 +0xaa

goroutine 7 [chan send]:
main.other(0xc000016120, 0xc0000140f0)
        /home/zeus/go/src/github.com/awesomeProject/pool.go:9 +0x37
created by main.main
        /home/zeus/go/src/github.com/awesomeProject/pool.go:25 +0xd6
exit status 2

【问题讨论】:

  • 您的代码尝试在通道上发送 2 个值,然后仅尝试从 if 接收。在无缓冲通道上,即使是第一次发送也会阻塞。发送者也应该关闭通道,而不是接收者。如果有多个发送者,应该有一个协调的 goroutine 关闭它(如果你想在通道上使用for range)。你想达到什么目标?
  • @dılosürücü 与play.golang.org/p/Whj2ccwIw9I比较
  • @dılosürücü 是的,我试过了。它与您的问题中的代码相同。你想用你的代码实现什么?

标签: go async-await


【解决方案1】:

你有一个无缓冲的频道,这意味着你不能在它上发送,直到有东西等待接收。

所以当你这样做时:

wg.Wait()

在你做之前

for v := range myChanel

你永远无法找到接收器。

无论如何,在使用无缓冲通道时,我从来不需要使用等待组,根据我的经验,您只有在处理并发的事情时才需要它们没有通道。你可以这样做:https://play.golang.org/p/-SUuXGlFd1E

【讨论】:

  • 对于多个发送者,通常使用 WaitGroup 正确关闭通道:go func() { wg.Wait(); close(ch) }()。在实际代码中,要接收的元素数量通常不会提前知道。
【解决方案2】:

我解决了

run it

package main

import (
    "fmt"
    "sync"
    "time"
)

func other(c chan int, wg *sync.WaitGroup) {
    time.Sleep(time.Second*1)
    c <- 455
    wg.Done()
}

func addInt(c chan int, d int, wg *sync.WaitGroup) {
    c <- d
    wg.Done()
}
func main() {

    var wg sync.WaitGroup
    myChanel := make(chan int)

    wg.Add(2)

    go addInt(myChanel, 5, &wg)
    go other(myChanel, &wg)

    go func() {
        wg.Wait()
        close(myChanel)
    }()

    for v := range myChanel {
        fmt.Println(v)
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 2016-09-21
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多