前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言学习笔记 | Sync包与同步原语

Go语言学习笔记 | Sync包与同步原语

作者头像
windealli
发布2024-04-16 13:01:02
840
发布2024-04-16 13:01:02
举报
文章被收录于专栏:windealliwindealli

一、引言

并发模型和Go语言的核心特性之一,Go语言的并发模型主要基于goroutineschannelgoroutine是由Go运行时管理的轻量级线程,它们使用非常少的内存,并且可以快速地创建和销毁。channel则是用于在goroutines之间传递消息的管道,它们可以是同步的也可以是异步的,为数据交换提供了一种安全且简单的方式。

然而,并非所有的并发问题都最适合用channels来解决。在某些情况下,直接使用同步原语来控制对共享资源的访问会更加高效和直接。

Go的标准库sync提供了多种同步工具,包括互斥锁(Mutex)、读写锁(RWMutex)、等待组(WaitGroup)和一次性执行(Once)等,这些都是我们将在本文中深入探讨的主题。

本文旨在介绍Go语言中的同步原语和锁,解释它们的工作原理,以及如何在实际编程中正确地使用它们。

二、同步原语:标准库sync

Go 语言在 sync 包中提供了一些同步原语,包括常见的 sync.Mutex、sync.RWMutex、sync.WaitGroup、sync.Once 和 sync.Cond:

[sync.Mutex](https://draveness.me/golang/tree/sync.Mutex) (互斥锁)

  • Mutex是最基本的同步原语之一,用于保护共享资源,防止多个goroutine在同一时间对同一资源进行读写,从而避免竞态条件。
  • Mutex提供了LockUnlock方法,用于在访问共享资源前后加锁和解锁。当一个goroutine获得了Mutex锁,其他尝试获取该锁的goroutine会阻塞,直到锁被释放。

sync.RWMutex(读写锁)

  • RWMutex是一种特殊类型的互斥锁,它允许多个goroutine同时读取共享资源,但在写入时需要独占访问。
  • RWMutex提供了RLockRUnlock方法用于读操作的锁定和解锁,以及LockUnlock方法用于写操作。这种锁机制在读多写少的场景下非常有用,因为它可以提高并发性能。

WaitGroup

  • WaitGroup用于等待一组goroutine完成。它在协调多个goroutine执行结束时非常有用,比如在主goroutine中等待一组工作goroutine完成任务。
  • 通过Add方法设置计数器,每启动一个工作goroutine就增加计数。工作goroutine完成后调用Done(本质上是Add(-1))来减少计数器。Wait方法会阻塞调用它的goroutine,直到计数器为零。

Once

  • Once是一个同步原语,它能保证在多个goroutine中只有一个能执行某个操作,且只执行一次。这在初始化共享资源或执行只需要运行一次的设置代码时非常有用。
  • Once只有一个方法Do,它接收一个函数作为参数,确保这个函数在程序运行期间只被执行一次,无论它被多少个goroutine调用。

Cond(条件变量)

  • Cond实现了条件变量,一个能够阻塞goroutine直到某个条件为真的同步原语。条件变量总是与互斥锁(Mutex)一起使用,以避免竞态条件。
  • Cond提供了Wait方法来挂起当前goroutine,直到被SignalBroadcast方法唤醒。Signal唤醒等待队列中的一个goroutine,而Broadcast唤醒所有等待的goroutine。

三、同步原语与Channel比较

Channel应用场景

Channel是一种用于在不同的goroutine之间进行通信和同步的机制。适用场景包括:

  • 在多个goroutine之间传递数据或消息。
  • 实现生产者-消费者模式,其中一个goroutine负责生产数据,另一个或多个goroutine负责消费数据。
  • 实现并发任务的协调和同步。

同步原语的应用场景

同步原语是一种用于控制并发访问共享资源的机制,如锁、条件变量等。适用场景包括:

  • 在多个goroutine之间对共享资源进行互斥访问,确保数据的一致性和正确性。
  • 控制并发执行的顺序,如使用互斥锁来实现临界区的互斥访问。
  • 实现线程间的等待和通知机制,如使用条件变量来实现等待和唤醒操作。

四、高级同步技术

原子操作(sync/atomic包)

原子操作是一种无需锁定的并发编程技术,可以保证对共享变量的操作是原子性的。在Go语言中,可以使用sync/atomic包提供的原子操作函数来实现。常见的原子操作包括原子增减、原子交换和原子比较交换等。原子操作适用于需要对共享变量进行简单的读写操作,并且不需要复杂的同步机制。

信号量模式(semaphore

信号量是一种用于控制并发访问资源的同步机制。它可以限制同时访问某个资源的线程或协程的数量。在Go语言中,可以使用channel或sync包中的WaitGroup来实现信号量模式。通过控制信号量的数量,可以实现对资源的并发访问控制,避免资源过度竞争和冲突。

Barrier(屏障):

屏障是一种同步机制,用于确保多个线程或协程在某个点上同步等待,直到所有线程都到达该点后才能继续执行。屏障可以用于解决多个线程或协程之间的协调问题,例如在并行计算中,当所有计算任务完成后,才能进行下一步的操作。在Go语言中,可以使用sync包中的WaitGroup来实现屏障。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-15,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 海天二路搬砖工 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、引言
  • 二、同步原语:标准库sync包
    • [sync.Mutex](https://draveness.me/golang/tree/sync.Mutex) (互斥锁)
      • sync.RWMutex(读写锁)
        • WaitGroup
          • Once
            • Cond(条件变量)
            • 三、同步原语与Channel比较
              • Channel应用场景
                • 同步原语的应用场景
                • 四、高级同步技术
                  • 原子操作(sync/atomic包)
                    • 信号量模式(semaphore)
                      • Barrier(屏障):
                      相关产品与服务
                      GPU 云服务器
                      GPU 云服务器(Cloud?GPU?Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                      http://www.vxiaotou.com