iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Go并发:使用sync.WaitGroup实现协程同步方式
  • 791
分享到

Go并发:使用sync.WaitGroup实现协程同步方式

GOsync协程 2022-06-07 20:06:51 791人浏览 八月长安
摘要

经常看到有人会问如何等待主协程中创建的协程执行完毕之后再结束主协程,例如如下代码: package main import ( "fmt" ) func main()

经常看到有人会问如何等待主协程中创建的协程执行完毕之后再结束主协程,例如如下代码:


package main
import (
    "fmt"
)
func main() {
    Go func() {
        fmt.Println("Goroutine 1")
    }()
    go func() {
        fmt.Println("Goroutine 2")
    }()
}

执行以上代码很可能看不到输出,因为有可能这两个协程还没得到执行主协程已经结束了,而主协程结束时会结束所有其他协程。

解决办法是可以在main函数结尾加上等待:

package main
import (
    "fmt"
    "time"
)
func main() {
    go func() {
        fmt.Println("Goroutine 1")
    }()
    go func() {
        fmt.Println("Goroutine 2")
    }()
    time.Sleep(time.Second * 1) // 睡眠1秒,等待上面两个协程结束
}

这并不是完美的解决方法,如果这两个协程中包含复杂的操作,可能很耗时间,就无法确定需要睡眠多久,当然可以用管道实现同步:


package main
import (
    "fmt"
)
func main() {
    ch := make(chan struct{})
    count := 2 // count 表示活动的协程个数
    go func() {
        fmt.Println("Goroutine 1")
        ch <- struct{}{} // 协程结束,发出信号
    }()
    go func() {
        fmt.Println("Goroutine 2")
        ch <- struct{}{} // 协程结束,发出信号
    }()
    for range ch {
        // 每次从ch中接收数据,表明一个活动的协程结束
        count--
        // 当所有活动的协程都结束时,关闭管道
        if count == 0 {
            close(ch)
        }
    }
}

上面的解决方案是比较完美的方案,但是Go提供了更简单的方法——使用sync.WaitGroup。

WaitGroup顾名思义,就是用来等待一组操作完成的。

WaitGroup内部实现了一个计数器,用来记录未完成的操作个数,它提供了三个方法,Add()用来添加计数。

Done()用来在操作结束时调用,使计数减一。

Wait()用来等待所有的操作结束,即计数变为0,该函数会在计数不为0时等待,在计数为0时立即返回。


package main
import (
    "fmt"
    "sync"
)
func main() {
    var wg sync.WaitGroup
    wg.Add(2) // 因为有两个动作,所以增加2个计数
    go func() {
        fmt.Println("Goroutine 1")
        wg.Done() // 操作完成,减少一个计数
    }()
    go func() {
        fmt.Println("Goroutine 2")
        wg.Done() // 操作完成,减少一个计数
    }()
    wg.Wait() // 等待,直到计数为0
}

可见用sync.WaitGroup是最简单的方式。

补充:Golang 中使用WaitGroup的那点坑

sync.WaitGroup对于golang开发者来说并不陌生,其经常作为多协程之间同步的一种机制。用好它势必会让你事半功倍,但是一旦错用将引发问题。

关于WaitGroup的使用网上有很多例子,在此就不做介绍了,我想说的是我在项目中使用WaitGroup遇到的坑。

在项目中,因为服务器有同步需求, 所以直接使用了WaitGroup,但是未考虑使用场景,结果在项目上线之后,高峰期的时候客户端经常出现卡顿,经过多方查找,才发现如果使用WaitGroup的时候,未启动单独的goroutine,那么极有可能造成主线程的阻塞,

所以我做了下面的测试(测试中,我把WaitGroup置于协程内):

import (
 "fmt"
 "sync"
 "time"
)
func main() {
    fmt.Println("main-1")
 testW()
 fmt.Println("main-2")
 time.Sleep(time.Duration(15) * time.Second) 
}
func testW() {
 fmt.Println("testW-1")
 go func() {
  var wg sync.WaitGroup
  fmt.Println("testW-2")
  testW1(&wg)
  fmt.Println("testW-5")
  wg.Wait()
  fmt.Println("testW-6")
 }()
}
func testW1(wg *sync.WaitGroup) {
 wg.Add(1)
 fmt.Println("testW-3")
 time.AfterFunc(time.Second*5, func() {
  wg.Done()
 })
 fmt.Println("testW-4") 
}

输出为:

main-1

testchan-1

main-2

testchan-2

testchan-3

testchan-4

testchan-5

// 过5秒

testchan-6

总结

将WaitGroup用于goroutine内,不会导致主线程的阻塞,同样可以实现同步的效果。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。如有错误或未考虑完全的地方,望不吝赐教。


您可能感兴趣的文档:

--结束END--

本文标题: Go并发:使用sync.WaitGroup实现协程同步方式

本文链接: https://www.lsjlt.com/news/30619.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python并发编程:同步与异步在Laravel中的实现方式
    随着互联网的快速发展,越来越多的Web应用程序需要同时处理多个客户请求。这就需要使用并发编程来提高应用程序的性能和响应能力。Python是一种非常流行的编程语言,也支持并发编程。本文将介绍Python并发编程中的同步和异步方法,并说明如何...
    99+
    2023-09-16
    并发 同步 laravel
  • React的组件协同使用实现方式
    目录嵌套父子组件通信兄弟组件通信抽离MixinReact的LinkedStateMixinReference:开发人员不用太过于关注UI层面的实现细节,考虑最多的也就是组件与组件之间...
    99+
    2024-04-02
  • Python并发编程:如何使用二维码实现同步?
    在日常的软件开发过程中,我们经常需要实现多个任务的并发执行。Python提供了多种方式来实现并发编程,比如多线程、多进程、协程等等。在本文中,我们将介绍如何使用Python的二维码模块实现多个线程之间的同步。 二维码是一种常见的编码方式,...
    99+
    2023-08-14
    并发 二维码 同步
  • 如何使用Python实现二维码同步并发编程?
    Python是一种高级编程语言,它能够帮助我们快速有效地编写各种程序。在今天的世界中,二维码已经成为了一种非常流行的技术,许多公司和组织都使用二维码来传输信息。本文将介绍如何使用Python实现二维码同步并发编程。 二维码的基本概念 在开始...
    99+
    2023-08-14
    并发 二维码 同步
  • Go语言的并发编程和协程使用
    Go语言作为一种强大的编程语言,以其简洁、高效的特性而著称。其中,其强大的并发编程和协程使用是其最大的亮点之一。本文将介绍Go语言中并发编程和协程的原理以及具体使用方法,并提供一些代码...
    99+
    2024-03-02
    go语言 协程 并发
  • 高效并发编程:使用Go WaitGroup和协程池
    在Go语言中,可以使用WaitGroup和协程池来实现高效的并发编程。1. WaitGroup:WaitGroup是一个计数器,用于...
    99+
    2023-10-08
    Golang
  • Go并发同步Mutex典型易错使用场景
    目录Mutex的4种易错使用场景1.Lock/Unlock 不成对出现2.Copy 已使用的 Mutex3.重入4.死锁解决策略Mutex的4种易错使用场景 1.Lock/Unloc...
    99+
    2024-04-02
  • Go语言中如何实现路径同步和并发?
    Go语言是一门支持并发编程的高级编程语言。在Go语言中,我们可以使用goroutine和channel等语言特性来实现路径同步和并发操作。本文将介绍如何在Go语言中实现路径同步和并发,并给出一些示例代码。 一、路径同步 在Go语言中实现路径...
    99+
    2023-06-18
    同步 并发 path
  • 对象同步:GO语言、Javascript的不同实现方式
    对象同步:GO语言、JavaScript的不同实现方式 随着计算机技术的不断发展,人们对程序性能和并发性能的要求越来越高。作为一种高效、并发性能出色的编程语言,GO语言一直备受开发者的青睐。而JavaScript作为前端开发的主流语言,也在...
    99+
    2023-09-15
    对象 同步 javascript
  • 如何在ASP编程中使用算法实现同步和并发?
    ASP是一种流行的Web应用程序开发框架,它支持多种编程语言,包括VBScript和JavaScript。在ASP编程中,同步和并发是两个重要的概念,因为它们可以帮助我们管理并发请求和数据访问。在本文中,我们将讨论如何使用算法实现ASP编程...
    99+
    2023-07-07
    同步 并发 编程算法
  • go同步协程的必备工具WaitGroup怎么使用
    本篇内容主要讲解“go同步协程的必备工具WaitGroup怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go同步协程的必备工具WaitGroup怎么使用”吧!1. 简介本文将介绍 Go ...
    99+
    2023-07-05
  • Python中的并发编程:如何实现同步?
    Python是一种支持多种编程范式的语言,其中并发编程是一种非常重要的范式。在Python中,我们可以使用多种方式实现并发编程,其中之一就是同步。本文将介绍Python中的并发编程,重点讲解如何实现同步。 一、什么是并发编程? 在计算机科学...
    99+
    2023-09-16
    并发 同步 laravel
  • 使用Golang的同步技术实现高性能并发
    在Golang中,可以使用以下同步技术来实现高性能并发:1. Mutex:使用互斥锁(Mutex)来保护共享资源的访问。互斥锁只允许...
    99+
    2023-10-08
    Golang
  • 如何用 Go 和 Bash 实现同步开发?
    Go和Bash是两种不同的编程语言,但它们都是非常强大的工具。在软件开发中,我们经常需要协同工作,同时进行开发和维护不同的代码库。本文将介绍如何使用Go和Bash实现同步开发。 一、为什么选择Go和Bash Go是一种高效、现代化的编程语言...
    99+
    2023-08-03
    bash 同步 开发技术
  • Go并发编程:通道与同步原语的运用
    综上所述,go 中的通道和同步原语是并发编程中至关重要的工具。通道用于安全地交换数据,而同步原语用于控制 goroutine 的并发执行。具体来说,通道允许 goroutine 传递数据...
    99+
    2024-05-11
    go 并发
  • 使用golang进行Select Channels Go并发式编程的异步处理方法
    在Go语言中,可以使用`select`语句来处理channel的异步操作。`select`语句可以同时监听多个channel的操作,...
    99+
    2023-10-08
    Golang
  • Kotlin使用协程实现高效并发程序流程详解
    目录1.协程的基本用法2.更多的作用域构建器3.使用协程简化回调的写法协程属于Kotlin中非常有特色的一项技术,因为大部分编程语言中是没有协程这个概念的。那么什么是协程呢?它其实和...
    99+
    2023-01-18
    Kotlin协程实现并发 Kotlin协程与并发
  • 高并发RPC:使用Go WaitGroup实现分布式调用
    在Go中,可以使用sync包中的WaitGroup来实现高并发RPC的分布式调用。WaitGroup是一个计数器,用于等待一组gor...
    99+
    2023-10-12
    Go语言
  • Python并发编程:如何利用二维码实现同步?
    在现代计算机系统中,多线程并发编程已经成为了一种标配。然而,在并发编程中,同步是非常重要的一环。在Python中,我们可以使用多种同步机制,如锁、信号量、条件变量等。但是,在某些场景下,我们可能需要使用一些更加特殊的同步方式,比如利用二维...
    99+
    2023-08-14
    并发 二维码 同步
  • 异步协程开发指南:实现高并发的推荐算法
    异步协程开发指南:实现高并发的推荐算法引言:在当今互联网时代,推荐算法的重要性不言而喻。无论是电商平台还是社交媒体,用户量巨大且复杂的用户关系网络都需要推荐算法来提供个性化的推荐服务。然而,随着用户数量的增长和用户行为数据的急剧增加,传统的...
    99+
    2023-12-18
    异步 协程 推荐算法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作