当前位置: 首页 > news >正文

【Golang】Golang中有哪些方式可以进行安全读写共享变量

文章目录

  • 前言
  • 一、介绍
    • 1. sync.Mutex
    • 2. sync.RWMutex
    • 3. sync/atomic
    • 4. channel
    • 5. sync.Map
  • 二、代码实现
      • 2.1 使用sync.Mutex
      • 2.2 使用sync.RWMutex
      • 2.3. 使用sync/atomic
      • 2.4使用channel
      • 2.4使用sync.Map
  • 三、总结


前言

在并发编程中,安全地读写共享变量是一个非常重要的问题。Go语言(Golang)提供了多种机制来确保在多线程环境下对共享变量的安全访问。本文将介绍几种常见的方式,包括sync.Mutex、sync.RWMutex、sync/atomic、channel和sync.Map,并通过代码示例展示如何使用这些机制。


一、介绍

1. sync.Mutex

sync.Mutex是Go语言中最基本的互斥锁,用于保护共享资源的读写。它通过锁定和解锁来确保同一时间只有一个goroutine可以访问共享变量。

2. sync.RWMutex

sync.RWMutex是一种读写锁,允许多个读操作同时进行,但写操作是互斥的。它比sync.Mutex更适合读多写少的场景。

3. sync/atomic

sync/atomic包提供了底层的原子操作,可以对整数和指针类型进行原子读写操作,适用于简单的计数器或标志位等场景。

4. channel

channel是Go语言中的一种通信机制,可以用来在多个goroutine之间安全地传递数据。通过channel可以实现对共享变量的安全读写。

5. sync.Map

sync.Map是Go 1.9引入的一种并发安全的map,适用于需要频繁读写的场景。

二、代码实现

2.1 使用sync.Mutex

package mainimport ("fmt""sync"
)var (mutex     sync.MutexsharedVar int
)func read() {mutex.Lock()defer mutex.Unlock()fmt.Println("Read:", sharedVar)
}func write(value int) {mutex.Lock()defer mutex.Unlock()sharedVar = valuefmt.Println("Write:", sharedVar)
}func main() {var wg sync.WaitGroupwg.Add(2)go func() {defer wg.Done()read()}()go func() {defer wg.Done()write(42)}()wg.Wait()
}

2.2 使用sync.RWMutex

package mainimport ("fmt""sync"
)var (rwMutex   sync.RWMutexsharedVar int
)func read() {rwMutex.RLock()defer rwMutex.RUnlock()fmt.Println("Read:", sharedVar)
}func write(value int) {rwMutex.Lock()defer rwMutex.Unlock()sharedVar = valuefmt.Println("Write:", sharedVar)
}func main() {var wg sync.WaitGroupwg.Add(2)go func() {defer wg.Done()read()}()go func() {defer wg.Done()write(42)}()wg.Wait()
}

2.3. 使用sync/atomic

package mainimport ("fmt""sync""sync/atomic"
)var sharedVar int64func read() {value := atomic.LoadInt64(&sharedVar)fmt.Println("Read:", value)
}func write(value int64) {atomic.StoreInt64(&sharedVar, value)fmt.Println("Write:", value)
}func main() {var wg sync.WaitGroupwg.Add(2)go func() {defer wg.Done()read()}()go func() {defer wg.Done()write(42)}()wg.Wait()
}

2.4使用channel

package mainimport ("fmt"
)func main() {ch := make(chan int)done := make(chan bool)// Writer goroutinego func() {ch <- 42done <- true}()// Reader goroutinego func() {value := <-chfmt.Println("Read:", value)done <- true}()// Wait for both goroutines to finish<-done<-done
}

2.4使用sync.Map

package mainimport ("fmt""sync"
)var sharedMap sync.Mapfunc read(key string) {if value, ok := sharedMap.Load(key); ok {fmt.Println("Read:", value)} else {fmt.Println("Key not found")}
}func write(key string, value interface{}) {sharedMap.Store(key, value)fmt.Println("Write:", value)
}func main() {var wg sync.WaitGroupwg.Add(2)go func() {defer wg.Done()write("key1", 42)}()go func() {defer wg.Done()read("key1")}()wg.Wait()
}

三、总结

在Go语言中,安全地读写共享变量是并发编程中的一个重要问题。本文介绍了几种常见的方法,包括sync.Mutex、sync.RWMutex、sync/atomic、channel和sync.Map。每种方法都有其适用的场景和优缺点:

  • sync.Mutex:适用于需要简单互斥锁的场景。
  • sync.RWMutex:适用于读多写少的场景。
  • sync/atomic:适用于简单的计数器或标志位等场景。
  • channel:适用于需要在多个goroutine之间传递数据的场景。
  • sync.Map:适用于需要频繁读写的并发场景。

根据具体的应用场景选择合适的并发控制方式,可以提高程序的性能和可维护性。希望本文能帮助你更好地理解和使用Go语言中的并发控制机制。


http://www.mrgr.cn/news/37316.html

相关文章:

  • 【工具分享】LockBit 3.0勒索病毒解密工具
  • JSP+Servlet+Mybatis实现列表显示和批量删除等功能
  • VBA过程代码密码解除
  • 【玩转贪心算法专题】56. 合并区间【中等】
  • Java通过base64将文件生成到指定位置
  • JAVA学习-练习试用Java实现“翻转字符串里的单词”
  • css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis的使用
  • css div多边框斜角边框
  • 面试小妙招:轻松绕过五大“坑”,展现真实自我
  • ARM汇编语言: lesson 2(ADD, SUB, MUL, set CPSR)
  • 文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《基于自适应时段划分的含氢微能网中长期变分辨率调度》
  • APP商业化变现模
  • 理解CPU上下文切换-下
  • springboot中有哪些方式可以解决跨域问题
  • Java中使用ZXing和QRCode生成二维码(附Demo)
  • 【SpringBoot详细教程】-06-Restful风格【持续更新】
  • Lod2城市三维模型是什么意思?
  • 你要的录音播放录音功能,直接用!Air201资产定位模组LuatOS快速入门
  • Django Web开发基础介绍
  • SemiDrive E3 MCAL 开发系列(4) – Gpt 模块的使用