Golang中除了加Mutex锁以外还有哪些方式可以安全读写共享变量?

在Go语言中,除了使用互斥锁(Mutex)以外,还有其他几种方式可以用于安全地读写共享变量:

  1. Channel:Go语言的核心理念之一就是“不通过共享内存来通信,而是通过通信来共享内存”。我们可以通过创建一个channel,然后通过发送和接收消息的方式来读写共享变量。这种方式在处理并发问题时非常有用,因为channel本身就提供了并发安全性。
    c := make(chan int)
    
    go func() { // goroutine 1
       x := <-c
       fmt.Println(x)
    }()
    
    go func() { // goroutine 2
       c <- 10
    }()
    
  2. 读写锁(sync.RWMutex:如果你的程序中读操作远多于写操作,那么使用读写锁可能会比互斥锁更有效率。读写锁允许多个协程同时读取变量,但是在写入时会阻止其他协程读写。
    var rwMutex sync.RWMutex
    var sharedVar int
    
    // Writer
    go func() {
       rwMutex.Lock()
       sharedVar = 10
       rwMutex.Unlock()
    }()
    
    // Reader
    go func() {
       rwMutex.RLock()
       fmt.Println(sharedVar)
       rwMutex.RUnlock()
    }()
    
  3. 原子操作(sync/atomic包):对于一些简单的数值和布尔类型,我们可以使用原子操作来读写共享变量,这会比使用互斥锁更有效率。
    var sharedVar int32
    
    // Writer
    go func() {
       atomic.StoreInt32(&sharedVar, 10)
    }()
    
    // Reader
    go func() {
       fmt.Println(atomic.LoadInt32(&sharedVar))
    }()
    
  4. sync.Once:如果你的共享变量只需要被初始化一次,那么可以使用sync.Once来确保初始化的并发安全性。
    var once sync.Once
    var sharedVar *SomeType
    
    // Initializer
    go func() {
       once.Do(func() {
           sharedVar = &SomeType{}
       })
    }()
    

以上这些方式都可以用于安全地读写共享变量,你可以根据具体的使用场景和需求来选择最合适的方式。

发表评论

后才能评论