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条)

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?