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结束时传送一个标示给信道。
    }

  • 相关阅读:
    Web 2.0网站命名的7个建议
    梦猪课堂视频系列
    计算机英文术语完全介绍
    PPT高手的思路
    在线RSS阅读器大比拼
    【百度现有服务】
    转载VFW编程实例(详)
    实现MFC扩展DLL中导出类和对话框 (转)
    Windows下编译 OpenSceneGraph(转)
    OSG静态编译 (转)
  • 原文地址:https://www.cnblogs.com/smallleiit/p/10844511.html
Copyright © 2011-2022 走看看