当前位置:首页 > 科技  > 软件

Go语言中的sync包同步原语

来源: 责编: 时间:2023-12-25 17:29:20 153观看
导读通过sync包掌握Go语言的并发并发是现代软件开发的基本方面,而Go(也称为Golang)为并发编程提供了一套强大的工具。在Go中用于管理并发的基本包之一是sync包。在本文中,我们将概述sync包,并深入探讨其最关键的同步原语之一:等

通过sync包掌握Go语言的并发

并发是现代软件开发的基本方面,而Go(也称为Golang)为并发编程提供了一套强大的工具。在Go中用于管理并发的基本包之一是sync包。在本文中,我们将概述sync包,并深入探讨其最关键的同步原语之一:等待组(Wait Groups)。h7E28资讯网——每日最新资讯28at.com

h7E28资讯网——每日最新资讯28at.com

sync包概述

sync包是Go的标准库包,为并发编程提供了同步原语。它为开发人员提供了协调和同步Goroutines的工具,确保并发任务的安全和有序执行。sync包提供的一些关键同步原语包括Mutexes、RWMutexes、Cond和Wait Groups。h7E28资讯网——每日最新资讯28at.com

等待组(Wait Groups)

1.什么是等待组?

等待组是Go中sync包提供的一个同步原语。它是一个简单但强大的工具,用于管理Goroutines的同步,特别是当您希望在继续之前等待一组Goroutines完成其任务时。h7E28资讯网——每日最新资讯28at.com

等待组在您有多个Goroutines同时执行独立任务,并且您需要确保所有任务都已完成后再继续主程序的场景中非常有用。h7E28资讯网——每日最新资讯28at.com

2.如何使用等待组

让我们通过一个代码示例来探索如何使用等待组:h7E28资讯网——每日最新资讯28at.com

package mainimport (    "fmt"    "sync"    "time")func worker(id int, wg *sync.WaitGroup) {    defer wg.Done() // Decrement the Wait Group counter when done    fmt.Printf("Worker %d is working/n", id)    time.Sleep(time.Second)    fmt.Printf("Worker %d has finished/n", id)}func main() {    var wg sync.WaitGroup    for i := 1; i <= 3; i++ {        wg.Add(1) // Increment the Wait Group counter for each Goroutine        go worker(i, &wg)    }    wg.Wait() // Wait for all Goroutines to finish    fmt.Println("All workers have finished.")}

在这个示例中,我们定义了一个名为worker的函数,该函数通过休眠一秒来模拟工作。我们启动了三个Goroutines,每个代表一个工作者,并使用sync.WaitGroup来协调它们的执行。h7E28资讯网——每日最新资讯28at.com

  • wg.Add(1) 在启动每个Goroutine之前增加等待组计数器。
  • wg.Done() 在worker函数中被延迟执行,以在Goroutine完成其工作时减少计数器。
  • wg.Wait() 阻塞主程序,直到所有Goroutines都完成,确保我们等待所有工作者的完成。

RWMutex(读写互斥锁)

RWMutex(读写互斥锁)是Go语言中的一个同步原语,它允许多个Goroutines同时读取共享数据,同时确保写入时的独占访问。在数据频繁读取但较少修改的场景中,它非常有用。h7E28资讯网——每日最新资讯28at.com

如何使用RWMutex

以下是一个简单的示例,演示如何使用RWMutex:h7E28资讯网——每日最新资讯28at.com

package mainimport (    "fmt"    "sync"    "time")var (    data        int    dataMutex   sync.RWMutex)func readData() int {    dataMutex.RLock() // Read Lock    defer dataMutex.RUnlock()    return data}func writeData(value int) {    dataMutex.Lock() // Write Lock    defer dataMutex.Unlock()    data = value}func main() {    // Read data concurrently    for i := 1; i <= 5; i++ {        go func() {            fmt.Println("Read Data:", readData())        }()    }    // Write data    writeData(42)    time.Sleep(time.Second)}

在这个示例中,多个Goroutines同时读取共享的data,而一个单独的Goroutine则对其进行写入。RWMutex确保多个读取者可以同时访问数据,但只有一个写入者可以在任何时候修改它。h7E28资讯网——每日最新资讯28at.com

Cond(条件变量)

1.什么是条件变量?

条件变量是一种同步原语,允许Goroutines在继续执行之前等待特定条件变为真。当您需要基于某些条件协调多个Goroutines的执行时,它们非常有用。h7E28资讯网——每日最新资讯28at.com

2.如何使用Cond

以下是一个基本示例,说明了如何使用条件变量:h7E28资讯网——每日最新资讯28at.com

package mainimport (    "fmt"    "sync"    "time")var (    conditionMutex sync.Mutex    condition      *sync.Cond    isReady        bool)func waitForCondition() {    conditionMutex.Lock()    defer conditionMutex.Unlock()    for !isReady {        fmt.Println("Waiting for the condition...")        condition.Wait()    }    fmt.Println("Condition met, proceeding.")}func setCondition() {    time.Sleep(2 * time.Second)    conditionMutex.Lock()    isReady = true    condition.Signal() // Signal one waiting Goroutine    conditionMutex.Unlock()}func main() {    condition = sync.NewCond(&conditionMutex)    go waitForCondition()    go setCondition()    time.Sleep(5 * time.Second)}

在这个示例中,一个Goroutine使用condition.Wait()等待条件变为真,而另一个Goroutine将条件设置为true并使用condition.Signal()通知等待的Goroutine。h7E28资讯网——每日最新资讯28at.com

原子操作

1.什么是原子操作?

原子操作是作为单个、不可分割的工作单元执行的操作。它们通常用于在并发程序中安全地更新共享变量,而无需使用互斥锁。Go提供了一个名为atomic的包来进行原子操作。h7E28资讯网——每日最新资讯28at.com

2.如何使用原子操作

以下是一个演示原子操作的示例:h7E28资讯网——每日最新资讯28at.com

package mainimport (    "fmt"    "sync"    "sync/atomic"    "time")var (    counter int32    wg      sync.WaitGroup)func incrementCounter() {    defer wg.Done()    for i := 0; i < 100000; i++ {        atomic.AddInt32(&counter, 1)    }}func main() {    wg.Add(2)    go incrementCounter()    go incrementCounter()    wg.Wait()    fmt.Println("Counter:", atomic.LoadInt32(&counter))}

在这个示例中,两个Goroutines使用原子操作递增一个共享的counter变量。atomic.AddInt32函数确保递增操作是原子的,并且对并发访问是安全的。h7E28资讯网——每日最新资讯28at.com

选择正确的同步机制

在选择适当的同步机制时,请考虑以下准则:h7E28资讯网——每日最新资讯28at.com

  • 互斥锁(对于读取使用RWMutex,对于写入使用Mutex) 在你需要对访问进行细粒度控制时,非常适合保护共享数据。
  • 条件变量 在你需要基于特定条件协调Goroutines时非常有价值。
  • 原子操作 在你想避免互斥锁开销的情况下,对共享变量进行简单操作非常高效。
  • 始终选择最能满足特定用例要求的同步机制。

总之,Go语言在sync包中提供了一套多才多艺的同步机制,以及用于管理对共享资源的并发访问的原子操作。了解这些工具并为您的并发需求选择合适的工具是编写高效可靠的并发Go程序的关键。h7E28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-54015-0.htmlGo语言中的sync包同步原语

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: C++中使用宏定义一个函数:灵活性与风险并存

下一篇: Python Selenium实现自动化测试及Chrome驱动使用!

标签:
  • 热门焦点
  • 一加Ace2 Pro官宣:普及16G内存 引领24G

    一加Ace2 Pro官宣:普及16G内存 引领24G

    一加官方今天继续为本月发布的新机一加Ace2 Pro带来预热,公布了内存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引领,还有呢?#一加Ace2Pro#,2023 年 8 月,敬请期待。”同时
  • vivo TWS Air开箱体验:真轻 臻好听

    vivo TWS Air开箱体验:真轻 臻好听

    在vivo S15系列新机的发布会上,vivo的最新款真无线蓝牙耳机vivo TWS Air也一同发布,本次就这款耳机新品给大家带来一个简单的分享。外包装盒上,vivo TWS Air保持了vivo自家产
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • 一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    8月5日消息,此前就有爆料称,一加首款折叠屏手机将会在第三季度上市,如今随着时间临近,新机的各种消息也开始浮出水面。据悉,这款新机将会被命名为&ldquo;On
  • K6:面向开发人员的现代负载测试工具

    K6:面向开发人员的现代负载测试工具

    K6 是一个开源负载测试工具,可以轻松编写、运行和分析性能测试。它建立在 Go 和 JavaScript 之上,它被设计为功能强大、可扩展且易于使用。k6 可用于测试各种应用程序,包括 Web
  • 十个简单但很有用的Python装饰器

    十个简单但很有用的Python装饰器

    装饰器(Decorators)是Python中一种强大而灵活的功能,用于修改或增强函数或类的行为。装饰器本质上是一个函数,它接受另一个函数或类作为参数,并返回一个新的函数或类。它们通常用
  • ESG的面子与里子

    ESG的面子与里子

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之三伏大幕拉起,各地高温预警不绝,但处于厄尔尼诺大&ldquo;烤&rdquo;之下的除了众生,还有各大企业发布的ESG报告。ESG是&ldquo;环境保
  • 东方甄选单飞:有些鸟注定是关不住的

    东方甄选单飞:有些鸟注定是关不住的

    文/彭宽鸿编辑/罗卿东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一年多时间里,东方甄选要脱离抖音自立门户的传闻不绝于耳,&ldquo;7
  • 余承东:AI大模型技术的发展将会带来下一代智能终端操作系统的智慧体验

    余承东:AI大模型技术的发展将会带来下一代智能终端操作系统的智慧体验

    8月4日消息,2023年华为开发者大会(HDC.Together)今天正式开幕,华为发布HarmonyOS 4、全新升级的鸿蒙开发套件、HarmonyOS Next开发者预览版本等一系列
Top