dongpao1926 2019-03-11 14:07
浏览 31
已采纳

没有等待组,将数据从不同的go例程写入相同的chanel可以正常工作

When writing data into same channel using multiple go routines with waitgroup after waiting wg.Wait() getting exception saying all go routines are asleep or deedlock.

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

func CreateMultipleRoutines() {
    ch := make(chan int)

    for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
        wg.Add(1)
        go func() {
            for j := 0; j < 10; j++ {
                ch <- j
            }
            wg.Done() // indication of go routine is done to main routine
        }()
    }

    fmt.Println(runtime.NumGoroutine())
    wg.Wait()           //wait for all go routines to complete
    close(ch)           // closing channel after completion of wait fo go routines
    for v := range ch { // range can be used since channel is closed
        fmt.Println(v)
    }
    fmt.Println("About to exit program ...")
}

When tried to implement this without waitgroup I am able to read data from channel by looping exact number of times data pushed to channel but i cant range since there will be panic when we close channel. here is the example code

package main

import (
    "fmt"
    "runtime"
)

func main() {
    ch := make(chan int)


    for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
        go func(i int) {
            for j := 0; j < 10; j++ {
                ch <- j * i
            }
        }(i)
    }

    fmt.Println(runtime.NumGoroutine())

    for v := 0; v < 100; v++ {
        fmt.Println(<-ch)
    }
    fmt.Println("About to exit program ...")
}

I want to understand why waitgroup in wait state is still waiting even though all go routines are signalled Done() which inturn makes number of go routines to zero

  • 写回答

2条回答 默认 最新

  • dps43633 2019-03-11 14:19
    关注

    By default a chan holds no items, so all go routines are blocked on sending, until something reads from it. They never actually reach the wg.Done() statement.

    A solution would be to close the channel in it's own go routine. Wrap your wg.Wait() and close(ch) lines like this:

    go func() {
        wg.Wait() //wait for all go routines to complete
        close(ch) // closing channel after completion of wait fo go routines
    }()
    

    Then you can range over the channel, which will only close after all of the sending go routines have finished (and implicitly all values have been received).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA