Golang安全读写共享变量的方式详解

 更新时间:2024年05月20日 14:47:27   作者:刘铸纬  
互斥锁(Mutex)是一种常用的同步原语,用于防止多个协程同时访问共享资源,这篇文章主要介绍了Golang安全读写共享变量的方式,需要的朋友可以参考下

1. 使用互斥锁(Mutex)

互斥锁(Mutex)是一种常用的同步原语,用于防止多个协程同时访问共享资源。

package main
import (
    "fmt"
    "sync"
)
var (
    counter int
    mutex   sync.Mutex
)
func increment(wg *sync.WaitGroup) {
    defer wg.Done()
    mutex.Lock()
    counter++
    mutex.Unlock()
}
func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final Counter:", counter)
}

2. 使用channel

Go语言的核心理念之一就是“不通过共享内存来通信,而是通过通信来共享内存”。我们可以通过创建一个channel,然后通过发送和接收消息的方式来读写共享变量。这种方式在处理并发问题时非常有用,因为channel本身就提供了安全性。

package main
import (
    "fmt"
)
func increment(counter chan int, done chan bool) {
    for i := 0; i < 1000; i++ {
        value := <-counter
        value++
        counter <- value
    }
    done <- true
}
func main() {
    counter := make(chan int, 1)
    counter <- 0
    done := make(chan bool)
    for i := 0; i < 10; i++ {
        go increment(counter, done)
    }
    for i := 0; i < 10; i++ {
        <-done
    }
    fmt.Println("Final Counter:", <-counter)
}

3. 读写锁(sync.RWMutex)

如果程序中的读操作远多于写操作,那么使用读写锁可能会比互斥锁更有效率。读写锁允许多个协程同时读取变量,但是只允许同一时刻只有一个协程进行写入操作。

package main
import (
    "fmt"
    "sync"
)
var (
    counter int
    rwMutex sync.RWMutex
)
func read(wg *sync.WaitGroup) {
    defer wg.Done()
    rwMutex.RLock()
    fmt.Println("Counter:", counter)
    rwMutex.RUnlock()
}
func write(wg *sync.WaitGroup) {
    defer wg.Done()
    rwMutex.Lock()
    counter++
    rwMutex.Unlock()
}
func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go read(&wg)
    }
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go write(&wg)
    }
    wg.Wait()
}

4. 原子操作(sync/atomic包)

对于一些简单的数值或者布尔类型,我们可以使用原子操作来读写共享变量。

package main
import (
    "fmt"
    "sync"
    "sync/atomic"
)
var counter int64
func increment(wg *sync.WaitGroup) {
    defer wg.Done()
    atomic.AddInt64(&counter, 1)
}
func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final Counter:", counter)
}

5. sync.Once

如果共享变量只需要被初始化一次,可以使用sync.Once来确保初始化的并发安全性。

package main
import (
    "fmt"
    "sync"
)
var (
    once sync.Once
    initValue int
)
func initialize() {
    fmt.Println("Initializing...")
    initValue = 42
}
func doSomething() {
    once.Do(initialize)
    fmt.Println("Value:", initValue)
}
func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            doSomething()
        }()
    }
    wg.Wait()
}

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

到此这篇关于Golang安全读写共享变量的方式的文章就介绍到这了,更多相关Golang安全读写共享变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang NewRequest/gorequest实现http请求的示例代码

    golang NewRequest/gorequest实现http请求的示例代码

    本文主要介绍了golang NewRequest/gorequest实现http请求的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 在Gin框架中解决跨域问题的多种方法

    在Gin框架中解决跨域问题的多种方法

    在使用Go语言进行Web开发时,Gin框架因其简洁、高效的特点而被广泛使用,然而,在实际开发中,跨域问题(CORS, Cross-Origin Resource Sharing)是一个常见的挑战,本文将结合实际案例,详细介绍在Gin框架中解决跨域问题的多种方法,需要的朋友可以参考下
    2024-10-10
  • Golang Web 框架Iris安装部署

    Golang Web 框架Iris安装部署

    这篇文章主要为大家介绍了Golang Web 框架Iris安装部署,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 如何在Go中将[]byte转换为io.Reader

    如何在Go中将[]byte转换为io.Reader

    本文主要介绍了如何在Go中将[]byte转换为io.Reader,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Go 通过结构struct实现接口interface的问题

    Go 通过结构struct实现接口interface的问题

    这篇文章主要介绍了Go 通过结构struct实现接口interface的问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Golang中的强大Web框架Fiber详解

    Golang中的强大Web框架Fiber详解

    在不断发展的Web开发领域中,选择正确的框架可以极大地影响项目的效率和成功,介绍一下Fiber,这是一款令人印象深刻的Golang(Go语言)Web框架,在本文中,我们将深入了解Fiber的世界,探讨其独特的特性,并理解为什么它在Go生态系统中引起了如此大的关注
    2023-10-10
  • golang高并发的深入理解

    golang高并发的深入理解

    golang从语言级别上对并发提供了支持,而且在启动并发的方式上直接添加了语言级的关键字。下面这篇文章主要给大家介绍了关于golang高并发的相关资料,需要的朋友可以参考下
    2019-03-03
  • Golang观察者模式优化订单处理系统实例探究

    Golang观察者模式优化订单处理系统实例探究

    当涉及到订单处理系统时,观察者设计模式可以用于实现订单状态的变化和通知,在这篇文章中,我们将介绍如何使用Golang来实现观察者设计模式,并提供一个基于订单处理系统的代码示例
    2024-01-01
  • go语言LeetCode题解1030距离顺序排列矩阵单元格

    go语言LeetCode题解1030距离顺序排列矩阵单元格

    这篇文章主要为大家介绍了go语言LeetCode题解1030距离顺序排列矩阵单元格,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 基于golang的简单分布式延时队列服务的实现

    基于golang的简单分布式延时队列服务的实现

    这篇文章主要介绍了基于golang的简单分布式延时队列服务的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论