为了解决数据竞争(data race),golang提供了一些原子操作型的包,比如atomic和mutex。它们各有千秋。
一、atomic
atomic是原子的意思。
由包提供的函数可知,
atomic主要可对集中类型进行提供:int32、int64、uint32、uint64、uintptr
我们知道在很多语言中,简单的赋值操作都很可能不是原子性的。例如在32位的机器上,赋值一个int64的变量。操作系统很首先对低32位进行赋值,其次再对高32位进行赋值。如果在此期间出现中断,那么这个变量就成了一个四不像的"bug"。
而atomic是golang底层对cpu指令集进行封装处理,保证赋值一气呵成,不会中断。提供了操作的原子性。
atomic包提供的操作函数:Add、Stroe、Load、Swap、CompareAndSwap
二、mutex
mutex则是golang提供的互斥锁,分为RWMutex(读写互斥锁)和Mutex(常规互斥锁)
RWMutex比较适用于读多写少的情况,读读间不会出现互斥。
Mutex则是常规锁,对统一对象进行读写都会产生锁
三、atomic和mutex的区别
3.1 atomic的包处于sync/atomic,mutex则是sync下的包
3.2 atomic是对cpu底层进行原子操作,不能通过程序干预。而mutex则是在语言层面的,操作自由度较高。
3.3 atomic省去了lock和unlock的操作,代码比较简洁
3.4 atomic因为其在底层就已封装好的特性,所以它在goroutine下的运行表现是连续不间断的;而mutex则在goroutine运行间由于锁的等待或持有等情况,断断续续地执行
3.5 atomic总体运行较快,但是如果存储数据的非常巨大,它的性能会大打折扣。因为每次更新atomic的数据,都会进行一次数据复制,数据越大效率下降越大
希望我的理解,对您会有少许帮助!