doushui3061 2017-05-25 11:28
浏览 62
已采纳

如何在不使用sync.WaitGroup的情况下防止死锁?

concurrent.go:

package main

import (
    "fmt"
    "sync"
)

// JOBS represents the number of jobs workers do
const JOBS = 2

// WORKERS represents the number of workers
const WORKERS = 5

func work(in <-chan int, out chan<- int, wg *sync.WaitGroup) {
    for n := range in {
        out <- n * n
    }
    wg.Done()
}

var wg sync.WaitGroup

func main() {
    in := make(chan int, JOBS)
    out := make(chan int, JOBS)

    for w := 1; w <= WORKERS; w++ {
        wg.Add(1)
        go work(in, out, &wg)
    }

    for j := 1; j <= JOBS; j++ {
        in <- j
    }
    close(in)

    wg.Wait()
    close(out)
    for r := range out {
        fmt.Println("result:", r)
    }

    // This is a solution but I want to do it with `range out`
    // and also without WaitGroups
    // for r := 1; r <= JOBS; r++ {
    //  fmt.Println("result:", <-out)
    // }
}

Example is here on goplay.

  • 写回答

2条回答 默认 最新

  • doujie3888 2017-05-25 14:25
    关注

    This is a proof of example syncing without waitgroup.

    Example in the Go playground

    package main
    
    import (
        "fmt"
    )
    
    // number of jobs workers do
    const JOBS = 10
    
    // number of workers
    const WORKERS = 2
    
    func work(in <-chan int, out chan<- int, done chan<- bool) {
        for n := range in {
            out <- n * n
        }
        done <- true
    }
    
    func main() {
        in := make(chan int, JOBS)
        out := make(chan int, JOBS)
        done := make(chan bool, WORKERS)
    
        // launch workers
        for w := 1; w <= WORKERS; w++ {
            go work(in, out, done)
        }
    
        // give jobs to workers
        for j := 1; j <= JOBS; j++ {
            in <- j
        }
        close(in)
    
        // list the results
        go func() {
            i := 0
            for r := range out {
                fmt.Println("result:", r)
    
                // when all jobs completed mark as done
                if i++; i == JOBS {
                    done <- true
                }
            }
        }()
    
        // wait for all goroutines to keep up
        // WORKERS + RESULT go routines
        for i := 0; i < WORKERS + 1; i++ {
            <- done
        }
    
        // prevent leaking chans
        close(out)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信
  • ¥30 Python调用dll文件输出Nan重置dll状态
  • ¥15 浮动div的高度控制问题。
  • ¥66 换电脑后应用程序报错
  • ¥50 array数据同步问题