download2014711 2017-12-28 01:10
浏览 26
已采纳

在Golang中,如何使用通道处理许多goroutine

I'm thinking start 1000 goroutines at the same time using for loop in Golang.
The problem is: I have to make sure that every goroutine has been executed.
Is it possible using channels to help me make sure of that?

The structure is kinda like this:

func main {
    for i ... {
        go ...
        ch?
    ch?
}
  • 写回答

3条回答 默认 最新

  • duanmao2650 2017-12-28 02:01
    关注

    Yes, try this:

    package main
    
    import (
        "fmt"
    )
    
    const max = 1000
    
    func main() {
        for i := 1; i <= max; i++ {
            go f(i)
        }
    
        s := 0
        for i := 1; i <= max; i++ {
            s += <-ch
        }
    
        fmt.Println(s)
    }
    
    func f(n int) {
        // do a job here
        ch <- n
    }
    
    var ch = make(chan int, max)
    

    output:

    500500
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • donglian1523 2017-12-28 01:46
    关注

    As @Andy mentioned You can use sync.WaitGroup to achieve this. Below is an example. Hope the code is self-explanatory.

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    func dosomething(millisecs int64, wg *sync.WaitGroup) {
        defer wg.Done()
        duration := time.Duration(millisecs) * time.Millisecond
        time.Sleep(duration)
        fmt.Println("Function in background, duration:", duration)
    }
    
    func main() {
        arr := []int64{200, 400, 150, 600}
        var wg sync.WaitGroup
        for _, n := range arr {
         wg.Add(1)
         go dosomething(n, &wg)
        }
        wg.Wait()
        fmt.Println("Done")
    }
    
    评论
  • douhu2525 2017-12-30 23:46
    关注

    I would suggest that you follow a pattern. Concurrency and Channel is Good but if you use it in a bad way, your program might became even slower than expected. The simple way to handle multiple go-routine and channel is by a worker pool pattern.

    Take a close look at the code below

    // In this example we'll look at how to implement
    // a _worker pool_ using goroutines and channels.
    
    package main
    
    import "fmt"
    import "time"
    
    // Here's the worker, of which we'll run several
    // concurrent instances. These workers will receive
    // work on the `jobs` channel and send the corresponding
    // results on `results`. We'll sleep a second per job to
    // simulate an expensive task.
    func worker(id int, jobs <-chan int, results chan<- int) {
        for j := range jobs {
            fmt.Println("worker", id, "started  job", j)
            time.Sleep(time.Second)
            fmt.Println("worker", id, "finished job", j)
            results <- j * 2
        }
    }
    
    func main() {
    
        // In order to use our pool of workers we need to send
        // them work and collect their results. We make 2
        // channels for this.
        jobs := make(chan int, 100)
        results := make(chan int, 100)
    
        // This starts up 3 workers, initially blocked
        // because there are no jobs yet.
        for w := 1; w <= 3; w++ {
            go worker(w, jobs, results)
        }
    
        // Here we send 5 `jobs` and then `close` that
        // channel to indicate that's all the work we have.
        for j := 1; j <= 5; j++ {
            jobs <- j
        }
        close(jobs)
    
        // Finally we collect all the results of the work.
        for a := 1; a <= 5; a++ {
            <-results
        }
    }
    

    This simple example is taken from here . Also the results channel can help you keep track of all the go routines executing the jobs including failure notice.

    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥40 基于51单片机实现球赛计分器功能
  • ¥15 关于#ubuntu#的问题:把PPT上的实验做一下,只需要实验截图就行(语言-r语言)
  • ¥15 cs2游戏画面卡住,应用程序sid与指挥者sid不匹配
  • ¥15 实验七:Pandas要有实验截图和代码
  • ¥15 TypeError: Make sure that the iterable only contains strings.
  • ¥35 电脑放图书馆,这是被黑了吗
  • ¥15 等高线中数据取消科学计数法
  • ¥15 Qt播放10路ffmpeg 视频流
  • ¥15 如何利用闲置机械硬盘变现
  • ¥15 信号处理中的凸优化问题