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

巴中哪里可以做公司网站网站开发工作安排

巴中哪里可以做公司网站,网站开发工作安排,手机网站设置方法,同城58招聘信息引言 ​ 在并发编程的世界里#xff0c;数据的一致性和线程安全是永恒的话题。Go语言以其独特的并发模型——goroutine和channel#xff0c;简化了并发编程的复杂性。然而#xff0c;在某些场景下#xff0c;我们仍然需要一种机制来保证操作的原子性。这就是sync/atomic.V…引言 ​ 在并发编程的世界里数据的一致性和线程安全是永恒的话题。Go语言以其独特的并发模型——goroutine和channel简化了并发编程的复杂性。然而在某些场景下我们仍然需要一种机制来保证操作的原子性。这就是sync/atomic.Value发挥作用的地方。 原子性并发编程的基石 ​ 原子性atomicity 是指一个或多个操作在执行过程中不会被中断的特性。这些操作要么全部完成要么全部不执行从而避免了中间状态的暴露。在Go中sync/atomic包提供了一组原子操作而Value类型则是一种特殊的原子操作用于存储和读取单个值。 适用场景读多写少的优化 ​ sync/atomic.Value利用了写时复制Copy-On-WriteCOW技术这使得它在读多写少的场景下表现卓越。由于COW的特性频繁的读操作不需要加锁而写操作则会产生一个新的副本这在内存使用上可能不是最经济的尤其是在内存较大且写操作频繁的情况下。 官方案例配置信息的动态更新 ​ 让我们通过一个官方示例来了解Value的使用。这个示例展示了如何使用Value来动态更新和读取服务器配置 package mainimport (sync/atomictime )func loadConfig() map[string]string {return make(map[string]string) }func requests() chan int {return make(chan int) }func main() {var config atomic.Value // holds current server configuration// Create initial config value and store into config.config.Store(loadConfig())go func() {// Reload config every 10 seconds// and update config value with the new version.for {time.Sleep(10 * time.Second)config.Store(loadConfig())}}()// Create worker goroutines that handle incoming requests// using the latest config value.for i : 0; i 10; i {go func() {for r : range requests() {c : config.Load()// Handle request r using config c._, _ r, c}}()} } 原理解析Value的内部机制 ​ Value的内部实现基于Go的interface{}类型通过unsafe包来实现原子操作。下面是Value的定义和写入操作的核心逻辑 // A Value provides an atomic load and store of a consistently typed value. // The zero value for a Value returns nil from Load. // Once Store has been called, a Value must not be copied. // // A Value must not be copied after first use. type Value struct {v any }​ Value 的底层是一个 intreface 结构体类型包含一个 interface 类型 v // efaceWords is interface{} internal representation. type efaceWords struct {typ unsafe.Pointerdata unsafe.Pointer }​ efaceWords 是 interface 类型的内部实现包含类型和值 写入操作 ​ 写入操作的关键在于确保类型一致性和原子性。首次写入时会禁用抢占确保写入过程不会被中断。后续写入则会检查类型一致性并原子性地更新数据。 var firstStoreInProgress byte// Store sets the value of the Value v to val. // All calls to Store for a given Value must use values of the same concrete type. // Store of an inconsistent type panics, as does Store(nil). func (v *Value) Store(val any) {if val nil {panic(sync/atomic: store of nil value into Value)}vp : (*efaceWords)(unsafe.Pointer(v))vlp : (*efaceWords)(unsafe.Pointer(val))for {typ : LoadPointer(vp.typ)if typ nil {// Attempt to start first store.// Disable preemption so that other goroutines can use// active spin wait to wait for completion.runtime_procPin()if !CompareAndSwapPointer(vp.typ, nil, unsafe.Pointer(firstStoreInProgress)) {runtime_procUnpin()continue}// Complete first store.StorePointer(vp.data, vlp.data)StorePointer(vp.typ, vlp.typ)runtime_procUnpin()return}if typ unsafe.Pointer(firstStoreInProgress) {// First store in progress. Wait.// Since we disable preemption around the first store,// we can wait with active spinning.continue}// First store completed. Check type and overwrite data.if typ ! vlp.typ {panic(sync/atomic: store of inconsistently typed value into Value)}StorePointer(vp.data, vlp.data)return} }流程 如果传入的值为空会产生一个 panic 通过 unsafe.Pointer 将old value 和 new value 转化成 efaceWords 类型 进入 for 循环 如果 typ nil 说明是第一次写入值那么进入到第一次赋值的流程 runtime_procPin() 禁止抢占标记当前G在M上不会被抢占使用 CompareAndSwapPointer 先尝试将typ设置为^uintptr(0)这个中间状态。如果失败则证明已经有别的线程抢先完成了赋值操作那它就解除抢占锁然后重新回到 for 循环第一步。如果设置成功则进入赋值阶段注意这里是 先赋值 data再赋值 typ因为我们是根据 typ 是否等于 nil 判断 对象是否被初始化所以最后赋值 typ 才能确保对象完成了初始化。 如果 typ 不等于 nil typ unsafe.Pointer(firstStoreInProgress) 判断初始化是否完成未完成则回到 for 循环起始处 如果初始化对象完成判断 typ ! vlp.typ 如果新写入的值不等于旧值则panic StorePointer(vp.data, vlp.data) 把 old value 原子性替换成 new value // StorePointer atomically stores val into *addr. // Consider using the more ergonomic and less error-prone [Pointer.Store] instead. func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)读取操作 ​ 读取操作相对简单它会原子性地获取当前值。如果值尚未初始化将返回nil。 // Load returns the value set by the most recent Store. // It returns nil if there has been no call to Store for this Value. func (v *Value) Load() (val any) {vp : (*efaceWords)(unsafe.Pointer(v))typ : LoadPointer(vp.typ)if typ nil || typ unsafe.Pointer(firstStoreInProgress) {// First store not yet completed.return nil}data : LoadPointer(vp.data)vlp : (*efaceWords)(unsafe.Pointer(val))vlp.typ typvlp.data datareturn }流程 首先载入 value if typ nil || typ unsafe.Pointer(firstStoreInProgress) 判断写入过程是否初始化完成 data : LoadPointer(vp.data) 原子性载入 old value // LoadPointer atomically loads *addr. // Consider using the more ergonomic and less error-prone [Pointer.Load] instead. func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)定义一个新的值 vlp : (*efaceWords)(unsafe.Pointer(val))然后将 old value 赋值给 new value COW 思想返回新的 value 1. 所以每次调用 Load 我们都是获取到了一个副本所以可以保证在并发读写时候的线程安全 总结与最佳实践 sync/atomic.Value是一个强大的工具适用于需要高并发读取的场景。然而它也有其局限性特别是在内存使用和写入操作的频率上。在使用Value时应当考虑以下几点 读多写少Value最适合的场景是读操作远多于写操作。内存效率频繁的写入可能会因为COW机制导致内存使用增加。类型安全写入操作要求类型一致性否则会引发panic 参考文献 Go sync/atomic包文档
http://www.dnsts.com.cn/news/18602.html

相关文章:

  • 成都洛可可设计有限公司网站在线优化
  • 坂田网站建设哪家好长沙装修公司前十强
  • 网站代码案例简单展示网站模板
  • 企业网站建设大概需要多少钱国外免费ip地址和密码
  • 国内有多少家做网站的企业网站建设包括的内容
  • 房地产网站怎么做东莞网站设计精英
  • 杭州个人网站建设wordpress是什么语言
  • 长春建一个网站大概要多少钱婚恋网网站架构
  • 上海网站推广费用网站建设以及维护
  • 建筑公司网站封面图片做纺织外贸哪个贸易网站好
  • 国内著名网站建设公司海南网站制做的公司
  • 专门做中式的设计网站大连图文设计有限公司
  • 云建站互动营销经典案例
  • 个人网站布局下载网站建设公司优惠中
  • 什么软件能自己做网站战事新闻最新
  • 昔阳做网站公司上海哪个网站好用
  • 北京网站建设设计公司广安住房和城乡建设厅网站
  • 企业展示网站 价钱昆明小程序定制
  • 骏域网站建设专家电话php网站建设开发
  • 鄂州网站推广个人网站意义
  • 网站中主色调腾讯云wordpress帐号
  • 个人网站网址org域名为什么禁止备案
  • 网站建设上海诏业图片网站虚拟主机
  • 设置网站湘潭网站建设问下磐石网络
  • 深圳英文网站建设江苏固茗建设有限公司网站
  • 网站方案书什么东西品牌vi设计多少钱
  • 东莞疾控最新提醒网站站内优化
  • 建一个在线商城网站辽宁手机版建站系统开发
  • 网络营销平台搭建方案网站网站建设虚拟服务器
  • 苏州制作企业网站的网站空间怎么选择