首页 > 其他分享 >sync.WaitGroup

sync.WaitGroup

时间:2024-04-26 23:59:39浏览次数:27  
标签:wg WaitGroup Goroutine sync Add Done


sync.WaitGroup 是 Go 语言标准库中提供的一个同步原语,用于在并发环境中协调多个 Goroutine 的执行顺序,确保所有并发任务完成后再继续执行后续逻辑。以下是 sync.WaitGroup 的使用方法:

  1. 创建 WaitGroup:

    • 使用 sync.WaitGroup 类型的零值创建一个实例,无需调用任何构造函数:
      var wg sync.WaitGroup
      
  2. 添加计数:

    • 在启动 Goroutine 之前,使用 Add() 方法增加 WaitGroup 的计数器。传递一个正整数作为参数,表示即将启动的 Goroutine 数量。如果每个 Goroutine 对应一个任务,通常传入 1。
      wg.Add(1)
      

    如果需要同时启动多个相同任务的 Goroutine,可以传入相应数量,如 wg.Add(5) 表示将启动 5 个 Goroutine。

  3. 启动 Goroutine:

    • 在增加计数后,启动 Goroutine 并在其内部执行相关任务。在 Goroutine 函数中,记得在任务完成后调用 Done() 方法。
      go func() {
          // 任务代码
          ...
          
          // 任务完成,通知 WaitGroup
          wg.Done()
      }()
      
  4. 重复步骤 2 和 3:

  • 如有多个不同类型的任务或多个批次的 Goroutine 需要同步,可以重复步骤 2 和 3,每次启动新的 Goroutine 前调用 Add(),并在对应的 Goroutine 内部任务完成后调用 Done()
  1. 等待所有任务完成:

    • 在所有 Goroutine 启动完毕后,使用 Wait() 方法阻塞当前 Goroutine(通常是主 Goroutine),直到 WaitGroup 的计数器归零(即所有 Goroutine 调用过 Done())。

      wg.Wait()
      
    • Wait() 方法会阻塞,直到所有之前通过 Add() 添加的 Goroutine 完成任务并调用 Done() 减少了计数器。一旦计数器变为 0,Wait() 返回,表明所有 Goroutine 已经完成,可以继续执行后续的同步代码。

  2. 特殊情况:

    • 如果需要在 Add() 时减少计数器(例如,某个任务被取消,不再需要等待),可以传入负数作为 Add() 的参数。不过,这通常不是一个常见的用法,大多数情况下只需在启动 Goroutine 前 Add(),在任务完成后 Done()

总结起来,sync.WaitGroup 的使用流程如下:

  1. 创建 sync.WaitGroup 实例。
  2. 在启动每个 Goroutine 前,调用 wg.Add(1)
  3. 在每个 Goroutine 内部,执行任务代码,完成后调用 wg.Done()
  4. 在所有 Goroutine 启动后,调用 wg.Wait(),等待所有 Goroutine 完成。
  5. wg.Wait() 返回后,继续执行后续同步代码。

标签:wg,WaitGroup,Goroutine,sync,Add,Done
From: https://www.cnblogs.com/yubo-guan/p/18161111

相关文章

  • Java并发02---Synchronized的实现原理、锁的升级、锁的膨胀、对象头、锁的消除、偏向
    @目录何为synchronized前置知识:对象头锁的升级(锁的膨胀)偏向锁轻量级锁轻量级锁锁的消除何为synchronized我们知道,synchronized关键字能够将其修饰的代码块、方法、静态方法变成同步代码。我们在前文中已经介绍过了,使用volatile关键字修饰能保证变量在内存中的可见性,但不保证操作......
  • GO中的sync.Cond
    条件变量是基于互斥锁的,它必须基于互斥锁才能发挥作用,条件变量的初始化离不开互斥锁,并且它的方法有点也是基于互斥锁的//使当前goroutine进入阻塞状态,等待其他goroutine唤醒func(c*Cond)Wait(){}//唤醒一个等待该条件变量的goroutine,如果没有goroutine在等待,则该方法会立......
  • MySQL的在sync_binlog!=1造成1236报错【转】
    前言本文总结了主从复制的原理及日常运维的坑1.主从复制简介MySQL复制是指从一个MySQL主服务器(master)将数据拷贝到另一台或多台MySQL从服务器(slaves)的过程,将主数据库的DDL和DML操作通过二进制日志传到从库服务器上,然后在从服务器上对这些日志重新执行,从而使得主......
  • Kernel panic - not syncing: Out of memory: system-wide panic_on_oom is enabled
    内存不足,导致Java 进程被杀掉。 [1534.300650]Kernelpanic-notsyncing:Outofmemory:system-widepanic_on_oomisenabled[1534.301803]CPU:5PID:2930Comm:javaKdump:loadedTainted:GO5.10.0-60.18.0.50.r1083_58.hce2.x86_64#1[153......
  • 从源码入手详解ReentrantLock,一个比synchronized更强大的可重入锁
    写在开头随手一翻,发现对于Java中并发多线程的学习已经发布了十几篇博客了,多线程是Java基础中的重中之重!因此,可能还需要十几篇博客才能大致的讲完这部分的知识点,初学者对于这部分内容一定要多花心思,不可马虎!今天我们继续来学习一个重要知识点:ReentrantLockReentrantLock:是一种......
  • C# 异步编程Task(三) async、await
    一、async和await两个修饰符C#5.0的时候引入了async和await两个修饰符,成为异步编程的核心关键字。async是修饰符,表明方法含有异步操作,但并不是说整个方法是异步的。async修饰的方法会先同步执行到第一处await的地方而后开始异步。await可以理解为一异步特有的“return”。即返回......
  • synchronization(同步)
    并发进程之间的关系在内存中同时存在的若干个进程/线程,由操作系统的调度程序采用适当的策略将他们调度至cpu上运行,同时维护他们的状态队列。多个并发进程/线程从宏观上是同时在运行;从微观的角度看,他们的运行过程是走走停停;并发的进程/线程是交替执行(Interleaving);Linux操......
  • lsyncd+rsync实时备份
    数据实时备份这里采用lsyncd+rsync实现服务器之间数据实时同步服务端配置备份服务器执行这个脚本,确保服务启动#配置rsyncd服务端的全部流程,也可以写成脚本,一键安装#/bin/bashyuminstallrsync-ycat>/etc/rsyncd.conf<<'EOF'uid=wwwgid=wwwport=873fake......
  • 30 天精通 RxJS (23):Subject, BehaviorSubject, ReplaySubject, AsyncSubject
    昨天我们介绍了Subject是什么,今天要讲Subject一些应用方式,以及Subject的另外三种变形。Subject昨天我们讲到了Subject实际上就是ObserverPattern的实例,他会在内部管理一份observer的清单,并在接收到值时遍历这份清单并送出值,所以我们可以这样用Subjectvarsubject......
  • V4L2 - Pipeline_Define & Async_Register & Pipeline_Create
       异步注册存在的根本原因就是:    注册时一定要表明subdev之间的层级关系,所以存在两个注册方向    一是以当前节点寻找下一级节点,如果下一级具备注册条件,则注册下一级节点,并指明层级关系    二是一失败后,寻找上一级节点,如果上一级指明层级关系方法被......