zoukankan      html  css  js  c++  java
  • 21 go并发编程-下

    如何等待一组goroutine结束

    1. 使用不带缓冲区的channel实现。

    原理:
    每个goroutine都往一个channel里写入一个值,然后我们去遍历这个管道的数值,由于不带缓冲区,那么必须等到写入端写入一个值后,for循环才能循环下去。这样等循环完成后,那么goroutine也都执行完成了。
    实现前提:goroutine必须往channel写入一个值,否则for循环的时候会报deadlock的错误!
    代码如下所示:

    // main
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func process(i int, ch chan bool) {
    	fmt.Println("started Goroutine ", i)
    	time.Sleep(2 * time.Second)
    	fmt.Printf("GoRoutine %d ended
    ", i)
    	ch <- true //写入一个值,必须写入
    }
    
    func main() {
    	no := 3
    	exitChan := make(chan bool, no)
    	for i := 0; i < no; i++ {
    		go process(i, exitChan)
    	}
    	for i := 0; i < no; i++ { // 遍历这个channel
    		<-exitChan
    	}
    	fmt.Println("all goroutines are done!")
    }
    
    

    2. 使用sync.WaitGroup实现。

    先说说WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成。
    WaitGroup总共有三个方法:Add(delta int)、Done()、Wait()。简单的说一下这三个方法的作用。

    1. Add:添加或者减少等待goroutine的数量
    2. Done:相当于Add(-1)
    3. Wait:执行阻塞,直到所有的WaitGroup数量变成0
    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    func process(i int, wg *sync.WaitGroup) {
    	fmt.Println("started Goroutine ", i)
    	time.Sleep(2 * time.Second)
    	fmt.Printf("Goroutine %d ended
    ", i)
    	wg.Done()
    }
    
    func main() {
    	no := 10
    	var wg sync.WaitGroup
    	for i := 0; i < no; i++ {
    		wg.Add(1)
    		go process(i, &wg)
    	}
    	wg.Wait()
    	fmt.Println("all goroutines are done!")
    }
    
    
  • 相关阅读:
    第八章:简单之美——布尔代数和搜索引擎的索引
    第六章:信息的度量和作用
    第五章:隐马尔可夫模型
    第四章谈谈中文分词
    第二章:自然语言处理———从规则到统计
    转:中文分词算法笔记
    NLTK之WordNet 接口【转】
    sentiwordnet的简单使用
    20169202 2016-2017-2 《移动平台开发实践》实验总结--七周
    20169202 2016-2017-2《移动平台》第七周学习总结
  • 原文地址:https://www.cnblogs.com/liaojiafa/p/9450166.html
Copyright © 2011-2022 走看看