dsj60862 2019-03-17 02:08
浏览 17
已采纳

限制运行的go例程

I have a list of urls to process, but I want to run a maximum number of goroutines at a time. For example, if I have 30 urls, I only want 10 goroutines working in parallel.

My attempt at this is the following:

parallel := flag.Int("parallel", 10, "max parallel requests allowed")
flag.Parse()
urls := flag.Args()

var wg sync.WaitGroup
client := rest.Client{}

results := make(chan string, *parallel)

for _, url := range urls {
    wg.Add(1)
    go worker(url, client, results, &wg)
}

for res := range results {
    fmt.Println(res)
}

wg.Wait()
close(results)

My understanding is that if I create a buffered channel of size parallel, then the code will block until I read off the results channel, which will unblock my code and allow another goroutine to be spawned. However, this code doesn't seems to block after processing all the urls. Can someone explain to me how I can use channels to limit the number of goroutines running?

  • 写回答

1条回答 默认 最新

  • dsznndq4912405 2019-03-17 02:24
    关注

    Create the desired number of workers instead of one worker per url:

    parallel := flag.Int("parallel", 10, "max parallel requests allowed")
    flag.Parse()
    
    // Workers get URLs from this channel
    urls := make(chan string) 
    
    // Feed the workers with URLs
    go func() {
        for _, u := range flag.Args() {
            urls <- u
        }
        // Workers will exit from range loop when channel is closed
        close(urls)
    }()
    
    var wg sync.WaitGroup
    client := rest.Client{}
    
    results := make(chan string)
    
    // Start the specified number of workers.
    for i := 0; i < *parallel; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for url := range urls {
                worker(url, client, results)
            }
        }()
    }
    
    // When workers are done, close results so that main will exit.
    go func() {
        wg.Wait()
        close(results)
    }()
    
    for res := range results {
        fmt.Println(res)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥35 引用csv数据文件(4列1800行),通过高斯-赛德尔法拟合曲线,在选取(每五十点取1点)数据,求该数据点的曲率中心。
  • ¥20 程序只发送0X01,串口助手显示不正确,配置看了没有问题115200-8-1-no,如何解决?
  • ¥15 Google speech command 数据集获取
  • ¥15 vue3+element-plus页面崩溃
  • ¥15 像这种代码要怎么跑起来?
  • ¥15 怎么改成循环输入删除(语言-c语言)
  • ¥15 安卓C读取/dev/fastpipe屏幕像素数据
  • ¥15 pyqt5tools安装失败
  • ¥15 mmdetection
  • ¥15 nginx代理报502的错误