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

网站服务器崩溃深圳布吉建网站公司

网站服务器崩溃,深圳布吉建网站公司,一级a做爰网站免费,凡科网站做的作品如何发布sync.Mutex 原理:一个共享的变量,哪个线程握到了,哪个线程可以执行代码 功能:一个性能不错的悲观锁,使用方式和Java的ReentrantLock很像,就是手动Lock,手动UnLock。 使用例子: v…

sync.Mutex

原理:一个共享的变量,哪个线程握到了,哪个线程可以执行代码

功能:一个性能不错的悲观锁,使用方式和Java的ReentrantLock很像,就是手动Lock,手动UnLock。

使用例子:

var mu sync.Mutex // 管理协程用的,主要是让协程同意结束后再运行调用协程
var cnt int
func add() {cnt++}
var wg sync.WaitGroup
func main() {for i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()defer mu.Unlock()mu.Lock()add()}()}wg.Wait()fmt.Print(cnt)
}
实现原理:

直接看源码好了,

func (m *Mutex) Lock() {// Fast path: grab unlocked mutex.if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { // 能拿到锁,就拿,拿不到就进入慢速模式if race.Enabled {race.Acquire(unsafe.Pointer(m))}return}// Slow path (outlined so that the fast path can be inlined)m.lockSlow()
}

lockSlow()是一个逻辑很多的方法,具体逻辑是:

  1. 自旋尝试:
    • 若当前是正常模式且锁持有时间较短,当前goroutine会自旋(循环检查锁状态),尝试避免立即阻塞。
    • 自旋条件:多核CPU、当前未处于饥饿模式、等待队列为空或自旋次数未超过阈值。
  2. 更新等待计数:
    • 通过原子操作增加state中的等待goroutine计数(高30位)。
  3. 进入阻塞或饥饿模式:
    • 正常模式:若自旋失败,将当前goroutine加入信号量等待队列(sema),并调用runtime_SemacquireMutex阻塞。
    • 饥饿模式:若当前goroutine等待时间超过阈值(1ms),触发饥饿模式。此时新来的goroutine直接进入队列尾部,不再自旋。
func (m *Mutex) lockSlow() {// 初始化变量操作,省略...for {// 这部分处理自旋尝试获取锁的逻辑if old&(mutexLocked|mutexStarving) == mutexLocked && runtime_canSpin(iter) {// 省略...runtime_doSpin()continue}new := old// 如果不是饥饿模式,尝试获取锁(new |= mutexLocked)if old&mutexStarving == 0 {new |= mutexLocked}// 如果锁已被占用或处于饥饿模式,增加等待者计数(new += 1 << mutexWaiterShift)if old&(mutexLocked|mutexStarving) != 0 {new += 1 << mutexWaiterShift}// 如果当前 goroutine 处于饥饿状态且锁被占用,切换到饥饿模式(new |= mutexStarving)if starving && old&mutexLocked != 0 {new |= mutexStarving}// 如果当前 goroutine 是被唤醒的:确保 mutexWoken 标志已设置(否则抛出异常);清除 mutexWoken 标志(new &^= mutexWoken)if awoke {if new&mutexWoken == 0 {throw("sync: inconsistent mutex state")}new &^= mutexWoken}// 尝试用 CAS 更新锁状态if atomic.CompareAndSwapInt32(&m.state, old, new) {if old&(mutexLocked|mutexStarving) == 0 {break }// 决定排队位置:如果是第一次等待(waitStartTime == 0),记录开始等待时间;否则使用 LIFO 顺序(queueLifo = true)queueLifo := waitStartTime != 0if waitStartTime == 0 {waitStartTime = runtime_nanotime()}// runtime_SemacquireMutex 将 goroutine 放入等待队列并阻塞runtime_SemacquireMutex(&m.sema, queueLifo, 2)// 被唤醒后:检查是否等待超时(超过 1ms),更新饥饿状态;重新读取锁状态starving = starving || runtime_nanotime()-waitStartTime > starvationThresholdNsold = m.state// 如果是饥饿模式:if old&mutexStarving != 0 {// 检查状态是否一致if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 {throw("sync: inconsistent mutex state")}// 计算状态增量: 设置 mutexLocked;减少等待者计数;如果不再饥饿或只有一个等待者,退出饥饿模式delta := int32(mutexLocked - 1<<mutexWaiterShift)if !starving || old>>mutexWaiterShift == 1 {delta -= mutexStarving}// 原子更新状态并退出循环atomic.AddInt32(&m.state, delta)break}awoke = trueiter = 0} else {old = m.state}}
}

在这里插入图片描述
Goroutine A 获取锁(Lock()快速路径成功)。
Goroutine B 尝试获取锁,进入慢速路径:
自旋数次后失败,增加等待计数,进入队列阻塞。
Goroutine A 释放锁(Unlock()):
唤醒Goroutine B,新来的Goroutine C可与B竞争锁。

在这里插入图片描述
Goroutine B 等待超过1ms,触发饥饿模式。
Goroutine C 新到达,直接进入队列尾部,不自旋。
Goroutine A 释放锁:
直接将锁交给队列头部的Goroutine B。
Goroutine B 释放锁后,若队列中无等待者,退出饥饿模式。

作者:ShanekAI
链接:https://juejin.cn/post/7488246529430487077
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

整体逻辑大致来说就是:Go 的 sync.Mutex 在竞争不激烈时,会采用短暂的 自旋锁 机制。自旋锁允许 Goroutine 在一小段时间内忙等待,而不是立即进入阻塞状态。这种策略避免了频繁的上下文切换开销。如果激烈的话,就进入饥饿模式,更改了逻辑,在饥饿模式里,停止自旋,直接将当前协程加入等待队列。当前线程执行完毕了,如果是饥饿模式,会把队列里第一个拿出来唤醒。

名词解释:

自旋:就是忙等,就是最简单的例子:

for state == 1{} // 不停地遍历,就好像在不停地自我旋转一样;直到state被其他线程修改了,才停止

文章转载自:

http://bUaiAyR2.jnhhc.cn
http://s90jETGf.jnhhc.cn
http://v5uQ3WEY.jnhhc.cn
http://uGXLVqJH.jnhhc.cn
http://ZEnGoDdV.jnhhc.cn
http://G0EHHwiE.jnhhc.cn
http://DxUx7RPq.jnhhc.cn
http://SLZPYhQn.jnhhc.cn
http://JeSWBz4y.jnhhc.cn
http://pLpGJDZg.jnhhc.cn
http://84u2fl0d.jnhhc.cn
http://1XVz06NF.jnhhc.cn
http://rXGl4ybD.jnhhc.cn
http://jZij20RB.jnhhc.cn
http://sSSpEf6D.jnhhc.cn
http://SetI7Sd1.jnhhc.cn
http://QDzGFyQE.jnhhc.cn
http://8FbRwwya.jnhhc.cn
http://BrXDzjld.jnhhc.cn
http://K2Q5Q9Ae.jnhhc.cn
http://dZjnP0MZ.jnhhc.cn
http://3FytaG6B.jnhhc.cn
http://M49OS3OT.jnhhc.cn
http://nUvKctUW.jnhhc.cn
http://tG4LWgoA.jnhhc.cn
http://e4w7LDed.jnhhc.cn
http://t2jy9NgG.jnhhc.cn
http://bK0I9JWq.jnhhc.cn
http://OL0xDRxR.jnhhc.cn
http://55SwBI2j.jnhhc.cn
http://www.dtcms.com/wzjs/753725.html

相关文章:

  • 网站投入费用中国建筑人才招聘
  • 生鲜网站开发WordPress与odoo接口
  • 网站搭建公司官网外贸网站搭建
  • 商务网站设计实训总结短视频制作软件免费
  • 网站在线动易网站栏目
  • 上海市建设安全协会网站特种工什么叫静态网站
  • 途牛网站建设功能需求分析微信企业网站源码下载
  • 城乡建设杂志官方网站wordpress上线apache
  • 奢侈品网站建设2023年免费域名推荐
  • 上海做高端网站最近国际新闻大事20条
  • 厦门响应式网站建设wordpress文章id排列
  • 网页设计做军事网站的感想衡水企业网站制作
  • 凡科做网站不好android 不装插件 wordpress
  • 网站后台多附件上传wordpress默认主体设置
  • 济宁网站建设有限公司宁波网站建设方案咨询
  • 滨州网站建设phpi企业网站做seo的必要性
  • 网站设计三把火科技不写代码做网站
  • wordpress网站托管百度网页版入口网址
  • 湘潭做网站品牌磐石网络crm客户管理系统免费软件
  • 网站单页生成器58同城赶集网
  • wordpress 7天热门seo排名关键词点击
  • 自己做本地网站济南网站建设是什么
  • 成都教育网站建设做网站常用代码向右浮动怎么写
  • 淮南网官方网站东莞市公司网站建设
  • 烟台百度网站建设推广网站设计上海
  • 电商网站设计模板建设工程教育网好还是环球网站好
  • 网站备案服务码口令是什么意思自己做一个入库出库系统
  • 衡阳市城乡建设协会官方网站邯郸市瑞荣网络科技有限公司
  • 做c语言的题目的网站沈阳软件定制开发
  • 东莞网络营销型网站营销型网站建设怎么收费