当前位置: 首页 > news >正文

龙象建设集团有限公司网站学做网站论坛会员账号

龙象建设集团有限公司网站,学做网站论坛会员账号,网络营销公司经营范围,网站信息组织优化文章目录 概要1、基本知识1.1 原子操作是什么1.2 CPU怎么实现原子操作的#xff1f; 2、atomic包2.1、 Add函数2.2、CompareAndSwap函数2.3、Swap函数2.4、Load函数2.5、Store函数 3、atomic.Value值 概要 atomic包是golang通过对底层系统支持的原子操作进行封装#xff0c;… 文章目录 概要1、基本知识1.1 原子操作是什么1.2 CPU怎么实现原子操作的 2、atomic包2.1、 Add函数2.2、CompareAndSwap函数2.3、Swap函数2.4、Load函数2.5、Store函数 3、atomic.Value值 概要 atomic包是golang通过对底层系统支持的原子操作进行封装而提供的原子操作包用于实现无锁化并发安全的操作数据。支持加法Add、比较并交换CompareAndSwap、直接交换Swap、设置指针变量值Store、获取指针变量值Load还设置了atomic.Value结构支持对象存储、获取、比较并交换、直接交换操作。 atmoic包怎么用以加法为例变量加法运算操作并不是原子性的包括从内存中取值放入加法寄存器、寄存器运算得到结果、将结果写回内存在并发环境下一个协程的运算结果可能被另一个覆盖从而导致丢失修改的问题例如以下代码的最后打印结果不会是10000。 var wg sync.WaitGroup var num 0func Add() {numwg.Done() } func main() {size : 10000wg.Add(size)for i : 0; i size; i {go Add()}wg.Wait()fmt.Println(num) }而以下代码时10000: var wg sync.WaitGroup var num int32 0func Add() {atomic.AddInt32(num, 1)wg.Done() } func main() {size : 10000wg.Add(size)for i : 0; i size; i {go Add()}wg.Wait()fmt.Println(num) }1、基本知识 1.1 原子操作是什么 原子操作是指在执行过程中不会被中断的操作要么全部执行完成要么完全不执行不存在部分执行的情况。原子操作可以看作是一个不可分割的单元其他线程或进程无法在其中间进行干扰或插入。 原子操作通常用于对共享数据进行读取、写入和修改等操作以保证数据的一致性和正确性。在多线程或多进程环境下如果多个线程或进程同时访问和修改同一份共享数据没有正确的同步机制或使用原子操作可能会导致数据竞争和不确定的行为。 常见的原子操作包括 原子读Atomic Read从内存中获取一个共享变量的值并确保其他线程或进程不会在读取过程中修改该值。原子写Atomic Write将一个值写入到共享变量并确保其他线程或进程不会在写入过程中读取或修改该值。原子加Atomic Add将一个特定的值与共享变量相加并将结果存回共享变量中确保其他线程或进程不会在加法过程中干扰。原子比较并交换Atomic Compare-and-Swap比较共享变量的当前值与预期值是否相等如果相等则将新值写入共享变量如果不相等则不做任何修改。该操作常用于实现同步机制和锁。 1.2 CPU怎么实现原子操作的 现在的CPU一般为多核处理器它底层实现原子操作的方式有多种下面介绍几种常见的方法 总线锁定在多核处理器中可以使用总线锁定机制来确保原子操作。当一个处理器需要执行原子操作时它会向总线发送一个请求锁定的信号。其他处理器在接收到该信号后将暂停对总线的访问以防止干扰正在进行的原子操作。只有当原子操作完成并释放锁定时其他处理器才能继续对总线进行访问。 缓存一致性协议多核处理器中的每个核心通常都具有自己的缓存这就需要确保各个核心之间的缓存数据的一致性。缓存一致性协议可以通过在多个核心之间共享和更新处理器**缓存行缓存在cpu核心本地缓存中的一条数据**的状态信息来实现原子操作。常见的缓存一致性协议有MESI多个核心更新数据时需要遵循以下原则 Modified修改状态当一个核心修改了一个缓存行中的数据时该缓存行将被标记为“修改”状态。此时其他核心的缓存中对应的缓存行就被视为无效Invalid即无效数据。 Exclusive独占状态当一个核心从内存中加载了一个缓存行到自己的缓存中并且该缓存行在其他核心的缓存中没有副本时该缓存行处于“独占”状态。这时其他核心需要读取或写入该数据时必须通过该核心进行访问独占状态的数据可以直接进行修改。 Shared共享状态当多个核心都拥有同一个缓存行的副本时该缓存行处于“共享”状态。此时对于读操作其他核心可以直接从自己的缓存中读取数据。对于写操作需要通过总线发出命令让其他缓存的状态更新为“失效”该缓存中数据更新为独占才能修改。 Invalid无效状态当一个核心修改了一个缓存行的数据时该缓存行在其他核心的数据状态会被标记为“无效”状态。这意味着其他核心需要重新从内存中加载最新的数据。 总的逻辑是当一个核心读取内存中数据在自己的本地缓存中并且只有该核心的缓存拥有该缓存行这个缓存行的状态为独占状态此时可直接进行读写操作其它缓存读取该缓存行需要通过总线想该核心发送请求进行读取此时缓存行状态变为共享。核心可以读取缓存行数据但修改需要先通过总线发起修改请求将其它核心的该缓存行数据置为无效再修改缓存行中数据看起来效率很低其实cpu会马上修改该缓存行修改完后缓存不会马上生效而是放入store buffer中再反送失效请求给所有核心由store buffer等待全部核心响应成功再生效缓存行的修改这段期间核心可以继续做其它事情。修改完成后缓存行为修改状态其他核心的该缓存行为无效状态此时若有核心读取该缓存行就将缓存行写入内存该核心上的缓存行状态更新为共享若是修改请求就将核心缓存行状态更新为无效。 原子指令现代的多核处理器通常会提供一些原子指令例如比较并交换compare and swap、加载和存储条件load-linked/store-conditional等。这些指令能够以硬件级别的原子方式执行从而保证对共享数据的访问是原子的。通过使用这些原子指令可以避免锁的开销并提供更高效的原子操作。 2、atomic包 Golang的atomic包的原子操作是通过CPU指令实现的。在大多数CPU架构中原子操作的实现都是基于32位或64位的寄存器。Golang的atomic包的原子操作函数会将变量的地址转换为指针型的变量并使用CPU指令对这个指针型的变量进行操作。 Golang的atomic包提供了一组原子操作函数包括Add、CompareAndSwap、Load、Store、Swap等函数。这些函数的具体作用如下 Add函数用于对一个整数型的变量进行加法操作并返回新的值。CompareAndSwap函数用于比较并交换一个指针型的变量的值。如果变量的值等于旧值就将变量的值设置为新值并返回true否则不修改变量的值并返回false。Load函数用于获取一个指针型的变量的值。Store函数用于设置一个指针型的变量的值。Swap函数用于交换一个指针型的变量的值并返回旧值。 让我们更具体地来看一下Golang的atomic包的原子操作 2.1、 Add函数 Add函数用于对一个整数型的变量进行加法操作并返回新的值。Add函数的定义如下 func AddInt32(addr *int32, delta int32) (new int32) func AddInt64(addr *int64, delta int64) (new int64) func AddUint32(addr *uint32, delta uint32) (new uint32) func AddUint64(addr *uint64, delta uint64) (new uint64) func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)其中addr表示要进行加法操作的变量的地址delta表示要加上的值。Add函数会将变量的值加上delta并返回新的值。 2.2、CompareAndSwap函数 CompareAndSwap函数用于比较并交换一个指针型的变量的值。如果变量的值等于旧值就将变量的值设置为新值并返回true否则不修改变量的值并返回false。CompareAndSwap函数的定义如下 func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool) func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool) func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool) func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool) func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)其中addr表示要进行比较和交换的变量的地址old表示旧值new表示新值。如果变量的值等于旧值就将变量的值设置为新值并返回true否则不修改变量的值并返回false。 2.3、Swap函数 Swap函数用于交换一个指针型的变量的值并返回旧值。Swap函数的定义如下 func SwapInt32(addr *int32, new int32) (old int32) func SwapInt64(addr *int64, new int64) (old int64) func SwapUint32(addr *uint32, new uint32) (old uint32) func SwapUint64(addr *uint64, new uint64) (old uint64) func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)其中addr表示要交换的变量的地址new表示新值。Swap函数会将变量的值设置为new并返回旧值。 2.4、Load函数 Load函数用于获取一个指针型的变量的值。Load函数的定义如下 func LoadInt32(addr *int32) (val int32) func LoadInt64(addr *int64) (val int64) func LoadUint32(addr *uint32) (val uint32) func LoadUint64(addr *uint64) (val uint64) func LoadUintptr(addr *uintptr) (val uintptr) func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)2.5、Store函数 Store函数用于设置一个指针型的变量的值。Store函数的定义如下 func StoreInt32(addr *int32, val int32) func StoreInt64(addr *int64, val int64) func StoreUint32(addr *uint32, val uint32) func StoreUint64(addr *uint64, val uint64) func StoreUintptr(addr *uintptr, val uintptr) func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)其中addr表示要设置的变量的地址val表示要设置的值。Store函数会将变量的值设置为val。 3、atomic.Value值 可以用来存储any类型对象的结构体存取操作均是原子操作具体方法如下 type Value struct {v any } // 加载Value中存的值 func (v *Value) Load() (val any) {} // 存储对象放入Value中 func (v *Value) Store(val any) {} // 交换Value中存的数据 func (v *Value) Swap(new any) (old any) {) // 比较并存储值必须铜类型且可比较采用使用该方法否则panic传入old、new对象如果old对象等于Value内存储的对象就将新的对象存入返回treu。否则false func (v *Value) CompareAndSwap(old, new any) (swapped bool) {}实践一下 package mainimport (fmtsync/atomic )type Config struct {Addr string }var config atomic.Valuefunc main() {conf1 : Config{Addr: 1.1.1.1,}conf2 : Config{Addr: 2.2.2.2,}config.Store(conf1)oldData : config.Swap(conf2)newData : config.Load()fmt.Println(oldData, newData)conf3 : Config{Addr: 3.3.3.3,}ok : config.CompareAndSwap(conf1, conf3)fmt.Println(ok, config.Load())ok config.CompareAndSwap(conf2, conf3)fmt.Println(ok, config.Load()) }输出 {1.1.1.1} {2.2.2.2} false {2.2.2.2} true {3.3.3.3}
http://www.hkea.cn/news/14562386/

相关文章:

  • 重庆电商网站建设费用宣城网站优化
  • 网站服务器配置单用什么编辑wordpress
  • 视频网站建设公司网站运营设计
  • 阿里云怎么做淘客网站闲鱼怎么推广自己的产品
  • 溧阳网站建设公司婚庆5个坑
  • 台州做网站软件南阳专业做网站公司哪家好
  • 自己做章网站沧州专业网站建设公司
  • 南京 网站制作公司小型培训机构管理系统
  • 网站如何生成静态郑州市哪里有网站建设
  • 基础微网站开发口碑好百度微信网站
  • 广州站服装外包加工网
  • 公司网站开发联系方式县区网站服务器机房建设
  • 广州响应网站建设网站换名称域名
  • 优美网站源码湘潭网站
  • 所有做运动的网站做公司网站的公司有哪些
  • 安阳网站公司临沂住房和城乡建设局网站
  • 网站设计知识网络推广都有什么方式
  • 网站建站企业互联网公司净利排名
  • 昆明网站建设公司哪家好百度平台
  • 黄岐建网站温岭新站seo
  • 企业类网站包括哪些360浏览器屏蔽某网站怎么做
  • 前几年做哪个网站能致富制作app软件要多少钱一个
  • 济南做网站哪里好北京移动端网站多少钱
  • 贵阳网站制作工具漳州网站建设网站运营
  • 唐山网站制作网络公司黑帽seo软件
  • 建设网站企业无锡市滨湖区建设局网站
  • 跨境电商网站开发技术学校网站建设工作计划
  • 全屏的翻页网站这么做o2o网站建设方案ppt
  • wordpress移动端视频做seo网站标题用什么符号
  • 佛山企业网站建设服务濮阳做网站公司