2022年10月更文挑战5-golang之共享变量并发包sync的使用

105 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

共享变量并发包sync的使用

前文

本文内容主要是针对于golang语言多协程状态下共享变量的并发处理操作,主要内容围绕sync这个golang包。文中内容主要为对现有知识的总结整理,可能存在不准确或不全面之处。

sync.Mutex互斥锁

import "sync"

var (
    mu      sync.Mutex
    base int
)

func A(item int) {
    mu.Lock()
    base = base + item
    mu.Unlock()
}

func B() int {
    mu.Lock()
    b := base
    mu.Unlock()
    return b
}

简单根据上面的代码所示,我们采用lock方法的调用进行锁定,而通过unlock方法进行解锁处理。mutex这把锁类似于synchroninzed这把锁,属于一种重量级锁。它会把对于该变量的所有操作,全部锁定在我们的锁之外禁止操作。

sync.RWMutex 读写锁

var mu sync.RWMutex
var base int
func Balance() int {
    mu.RLock() 
    defer mu.RUnlock()
    return balance
}

读写锁是一种轻量级的锁处理。像比如上面的锁来锁,它在锁定时不会锁定全部的操作。它允许多个读操作执行,但不允许多个写操作同时处理。当没有写模式的加锁时,任意协程都可以进行读模式的加锁。当对象处于非加锁状态时,才能够进行写模式的加锁。而当写模式进行加锁时,读模式的锁无法进行添加。读写锁的模式可以认为是共享独占锁的一种实现。

sync.Once 初始化

在某些情况下我们的程序需要进行数据的初始化处理。而如果初始化的内容比较多,那么将初始化转移到使用时再进行初始化是一种比较好的操作。

var once sync.Once
var icons map[string]image.Image
func Icon(name string) image.Image {
    once.Do(loadIcons)
    return icons[name]
}

比如上面的一段代码,只有在数据被访问时才会初始化,而通过sync.Once的使用,将会是一种兵法安全的操作,不会产生兵法问题。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。