本文介绍: atomic 包是 Go 语言用于进行原子操作标准库。原子操作是一种在多线程并发编程用来确保数据安全机制,它可以防止多个线程同时访问一个资源而导致的数据竞争问题atomic 包中的函数原子操作,它们在执行时不会被中断,从而确保操作的不可分割性。这对于执行复杂的操作,如比较交换,是非常重要的。在某些情况下,使用互斥锁来保护共享变量可能会导致额外的锁开销和上下文切换,从而影响性能atomic 包的原子操作不需要使用锁,可以减少这些开销。

作用与优势

atomic 包是 Go 语言用于进行原子操作的标准库。原子操作是一种在多线程并发编程用来确保数据安全机制,它可以防止多个线程同时访问一个资源而导致的数据竞争问题

atomic 包中的函数是原子操作,它们在执行时不会被中断,从而确保操作的不可分割性。这对于执行复杂的操作,如比较交换,是非常重要的。

在某些情况下,使用互斥锁来保护共享变量可能会导致额外的锁开销和上下文切换,从而影响性能。atomic 包的原子操作不需要使用锁,可以减少这些开销。

原子操作通常比互斥锁更高效,特别是在一些轻量级的操作中。在高并发的情况下,使用原子操作可以提高程序的性能

适用场景

atomic包中的函数

  1. atomic.AddInt32, atomic.AddInt64,atomic.AddUint32,atomic.AddUint64:原子地将指定的值加到一个整数变量上。
  2. atomic.LoadInt32,atomic.LoadInt64,atomic.LoadUint32,atomic.LoadUint64:原子地读取一个整数变量的值。
package main

import (
   "fmt"
   "sync"
   "sync/atomic"
   "time"
)

func main() {
   var counter int64
   var wg sync.WaitGroup

   for i := 0; i < 10; i++ {
      wg.Add(1)
      go func() {
         for j := 0; j < 1000; j++ {
            atomic.AddInt64(&amp;counter, 1)
         }
         wg.Done()
      }()
   }

   wg.Wait()
   fmt.Println("Counter value:", atomic.LoadInt64(&amp;counter))
}

  1. atomic.StoreInt32, atomic.StoreInt64, atomic.StoreUint32, atomic.StoreUint64:原子地将指定的值写入一个整数变量中。
package main

import (
   "fmt"
   "sync"
   "sync/atomic"
)

func main() {
   var value int64
   var wg sync.WaitGroup

   // 启动多个协程尝试存储
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go func(i int) {
         defer wg.Done()

         // 原子地将值设置协程编号
         atomic.StoreInt64(&amp;value, int64(i))
         fmt.Printf("Goroutine %d: Stored value %dn", i, i)
      }(i)
   }

   wg.Wait()
   fmt.Printf("Final value: %dn", value)
}


  1. atomic.CompareAndSwapInt32, atomic.CompareAndSwapInt64, atomic.CompareAndSwapUint32, atomic.CompareAndSwapUint64:比较交换比较当前addr地址里的值是不是old,如果不等于old,就返回false; 如果当前等于old,就把此地址的值替换new值,返回true
package main

import (
   "fmt"
   "sync"
   "sync/atomic"
)

func main() {
   var value int64 = 0
   var wg sync.WaitGroup

   // 启动多个协程尝试修改
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go func(i int) {
         defer wg.Done()

         // 尝试将值从旧值0修改为新值10
         swapped := atomic.CompareAndSwapInt64(&amp;value, 0, 10)
         if swapped {
            fmt.Printf("Goroutine %d: Value swapped successfullyn", i)
         } else {
            fmt.Printf("Goroutine %d: Value was not swappedn", i)
         }
      }(i)
   }

   wg.Wait()
   fmt.Printf("Final value: %dn", value)
}


  1. atomic.SwapInt32, atomic.SwapInt64, atomic.SwapUint32, atomic.SwapUint64:原子地交换一个整数变量的值。如果不需要比较旧值,只是比较粗暴地替换的话,就可以使用Swap方法

```go
package main

import (
   "fmt"
   "sync"
   "sync/atomic"
)

func main() {
   var value int64 = 5
   var wg sync.WaitGroup

   // 启动多个协程尝试交换
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go func(i int) {
         defer wg.Done()

         // 原子地交换值为新值10,并获取旧值
         oldValue := atomic.SwapInt64(&value, 10)
         fmt.Printf("Goroutine %d: Swapped value from %d to 10n", i, oldValue)
      }(i)
   }

   wg.Wait()
   fmt.Printf("Final value: %dn", value)
}


原文地址:https://blog.csdn.net/ldxxxxll/article/details/134732420

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_29344.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注