zoukankan      html  css  js  c++  java
  • golang中如何阻塞等待所有goroutines都完成

    有一天,一个人问了我此问题,回头仔细翻阅了一下资料,仔细的想了一下,这个问题的解决有两种方案。
    方案一:
    也是推荐方案,也是官方推荐方案,涉及到一个写并发经常关注的模块sync模块,利用里面的sync.WaitGroup去做
    代码如下:
    package main
    import(
            "fmt"
            "sync"
            "time"
            "runtime"
    )
    var wg sync.WaitGroup //定义一个同步等待的组
    func main() {
        maxProcs := runtime.NumCPU() //获取cpu个数
        runtime.GOMAXPROCS(maxProcs) //限制同时运行的goroutines数量
        for i:=0;i<10;i++{
                wg.Add(1)//为同步等待组增加一个成员
                go Printer(i)//并发一个goroutine
        }
        wg.Wait() //阻塞等待所有组内成员都执行完毕退栈
        fmt.Println("WE DONE!!!")
    }
    //定义一个Printer函数用于并发
    func Printer(a int)(){
            time.Sleep(2000 * time.Millisecond)
            fmt.Printf("i am %d ",a)
            defer wg.Done()
    }

    方案二:
    思路也不绕路,利用的channel的阻塞机制,直接上代码了。
    package main
    import(
            "fmt"
            "time"
            "runtime"
    )
    var num=14 //定义一工并发多少数量
    var cnum chan int
    func main(){
       maxProcs := runtime.NumCPU()// 获取cpu个数
        runtime.GOMAXPROCS(maxProcs)//限制同时运行的goroutines数量
        cnum=make(chan int,num) //make一个chan,缓存为num
        for i:=0;i<num;i++{
                go Printer(i)
        }
    // 下面这个for循环的意义就是利用信道的阻塞,一直从信道里取数据,直到取得跟并发数一样的个数的数据,则视为所有goroutines完成。
        for i:=0;i<num;i++{
                <-cnum
        }
        fmt.Println("WE DONE!!!")
    }



    func Printer(a int)(){
            time.Sleep(2000 * time.Millisecond)
            fmt.Printf("i am %d ",a)
            cnum <- 1 //goroutine结束时传送一个标示给信道。
    }

  • 相关阅读:
    信息系统开发平台OpenExpressApp - 支持列表分组(Group)
    WPF - 轻量级的开源XAML编辑器Kaxaml
    工作流 - 架构描述
    工作流 - 技术备忘录
    开源 - 轻型的表达式引擎 Flee
    敏捷实践(收集)
    人生就是......
    信息系统开发平台OpenExpressApp - 应用模型ApplicationModel
    软件观点 - 平台分类:系统平台、开发平台和开放平台
    软件产品线工程方法 - BAPO之架构(Architecture)
  • 原文地址:https://www.cnblogs.com/smallleiit/p/10844511.html
Copyright © 2011-2022 走看看