zoukankan      html  css  js  c++  java
  • 使用waitgroup在循环中开Goroutine处理并发任务

    简介

      实际项目中遇到了需要并发处理的任务,在for循环中用Go的Goroutine去处理任务遇到了一些问题,这里写一个demo记录一下简单的过程。

    同步的代码

      这里用一个简单的time.sleep模拟一下同步的代码,然后再看看开协程处理的不同之处:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
    
        // 同步代码
        lst := []int8{1,2,3}
        start := time.Now()
        for _,i := range lst{
            DeltaTask(i)
        }
        end := time.Now()
        ret := end.Sub(start)
        fmt.Printf("耗时:%v",ret)
    }
    
    // 模仿耗时的任务
    func DeltaTask(i int8){
        time.Sleep(time.Duration(i)*time.Second)
    }
    
    // 耗时:6.008863168s

    开协裎的写法

      这里直接上代码:

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    func main() {
    
        // 异步代码
        lst := []int8{1,2,3}
        start := time.Now()
        // 定义一个waitgroup
        wait := sync.WaitGroup{}
        for _,i := range lst{
            // tag +1
            wait.Add(1)
            // go一个匿名函数
            go func(delta int8){
                // tag -1
                defer wait.Done()
                DeltaTask(delta)
            }(i)
        }
        // 主线程等待 "计时器" 为0才往下走直到停止
        wait.Wait()
        end := time.Now()
        ret := end.Sub(start)
        fmt.Printf("耗时:%v",ret)
    }
    
    // 模仿耗时的任务
    func DeltaTask(i int8){
        time.Sleep(time.Duration(i)*time.Second)
    }
    // 耗时:3.005254124s

      这里最重要的就是WaitGroup的使用!可以跟Python并发编程中的join方法进行类比:因为在Go中主线程结束后意味着主线程中开的协裎也都挂了,所以一定要确保执行协裎任务时主线程一直处于wait的状态!

  • 相关阅读:
    SpringBoot 集成Log4j、集成AOP
    SpringBoot 集成JUnit
    SpringBoot yml文件语法
    SpringBoot 集成MyBatis、事务管理
    SpringBoot 集成Spring JDBC
    模板引擎简介
    SpringBoot 解决“不支持发行版本xx”的问题
    SpringBoot 全局异常处理
    SpringBoot 静态资源的配置
    SpringBoot的起步依赖
  • 原文地址:https://www.cnblogs.com/paulwhw/p/13904235.html
Copyright © 2011-2022 走看看