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

郑州建网站多少青岛中企动力科技股份有限公司

郑州建网站多少,青岛中企动力科技股份有限公司,家教网站如何建设,厦门seo屈兴东先看下go的sync.mutex是什么 type Mutex struct {state int32sema uint32 } 这里面有个sema#xff0c;这个就是信号量。 什么是信号量#xff1f; 什么是信号量#xff1f;_kina100的博客-CSDN博客 其实通俗的来说#xff0c;信号量就是信号灯#xff0c;但是他不是…先看下go的sync.mutex是什么 type Mutex struct {state int32sema uint32 } 这里面有个sema这个就是信号量。 什么是信号量 什么是信号量_kina100的博客-CSDN博客 其实通俗的来说信号量就是信号灯但是他不是个灯他是一个变量这个变量通过值来承担信号功能比如值为0的时候我们称之为假值为1的时候我们称之为真这就是信号量。 sema在mutex里面是怎么实现的 在go的sync.mutex里面 sema表面上来看就是个uint32但是实际上他底层是一个semaRoot结构体 type semaRoot struct {lock mutextreap *sudog // root of balanced tree of unique waiters.nwait atomic.Uint32 // Number of waiters. Read w/o the lock. } semaRoot里面有三个成员分别是 1lock这是一个mutex类型要注意的是这不是sync包里面的mutex这是runtime2包里面的mutex关于runtime包里的mutex其实用的地方也非常多可以看看这个go中runtime包里面的mutex是什么runtime.mutex解析_kina100的博客-CSDN博客 这个lock锁主要的作用是保护semaRoot结构体的访问防止多个goroutine竞争访问semaroot的时候出现并发问题。 2 treap实际上是一个平衡树balanced tree的root节点,他的主要作用其实就是存等待这个锁的goroutine当一个g进来请求锁的时候如果锁没有得到就开始进入等待他会被包装成一个sudog然后进入到treap里面启动休眠当上一个拿到锁的g释放锁后就会从treap里取出一个sudog唤醒获得锁 3nwait记录下现在等待该锁的g的数量原则上来说和treap的数量是一致的 如何加锁 先看一个重要的方法如何控制sema信号量 // 获取信号量 func cansemacquire(addr *uint32) bool {for {// 这里说明一下sema如果大于0说明资源充足不需要竞争如果sema等于0代表资源紧张需要互斥竞争同一资源了协程若没竞争到资源就进入等待状态了// 这里的sema的数值是在启用的时候就已经初始化设定的// 也就说如果我们不设定sema数值而他的初始值就是0那么sema锁在这一步永远都是renturn false的反过来说他已经退化成一个只有treap的队列这个很重要因为在go的底层很多地方都这么用他不用sema锁而是用了semaroot结构体当做一个存储g的队列比如sync.mutex就是这么用的v : atomic.Load(addr)if v 0 {// 拿不到你回去等着吧--包装成sudog进入treap进行等候return false}// 交换数值-1返回trueif atomic.Cas(addr, v, v-1) {return true}} } 再看加锁的方法 func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes int, reason waitReason) {// 获取当前操作该锁的goroutinegp : getg()// gp.m.curg 就是指向当前线程M上正在执行的 goroutine 的指针。// 判断获取的g是否是g所属m当前运行的g防止你正在操作锁的时候m已经切换到下一个g了if gp ! gp.m.curg {throw(semacquire not on the G stack)}// 尝试获取sema信号,获取成功就返回意思是拿到锁了if cansemacquire(addr) {return}// 没拿到锁// 初始化创建一个sudog对象s : acquireSudog()// 获取全局的sematable的根节点这个地方有点难以理解go的整个全局最大能同时存在251个semaroot实际上在快速处理的情况下go很难同时把251个都塞满极端情况下塞满的话就得考虑分布式拆分服务了单个服务已经庞大到需要同时存在251把锁这服务的复杂度难以想象root : semtable.rootFor(addr)t0 : int64(0)s.releasetime 0s.acquiretime 0s.ticket 0// 这个是阻塞分析用的一般来说不用管除非你搞底层研究阻塞分析需要记录时间这里的逻辑都是处理时间的if profilesemaBlockProfile ! 0 blockprofilerate 0 {t0 cputicks()s.releasetime -1}if profilesemaMutexProfile ! 0 mutexprofilerate 0 {if t0 0 {t0 cputicks()}s.acquiretime t0}// 循环处理for {// 按一定的规则判断锁的顺序如果不按这个顺序直接判定为死锁一般不用管必须开启GOEXPERIMENTstaticlockranking才有这玩意这玩意默认关闭lockWithRank(root.lock, lockRankRoot)// 等待锁的g的计数器1root.nwait.Add(1)// 再次尝试获取锁。成功就退出循环没啥好说的if cansemacquire(addr) {root.nwait.Add(-1)unlock(root.lock)break}// 再次尝试也没拿到锁进入treap的那个队列root.queue(addr, s, lifo)// 执行gopark这方法非常重要但是不需要关注gopark是go语言底层的一个方法他的作用是让goroutine挂起等待换个说法就是休眠等待被唤醒。它广泛存在于go底层中但是因为是底层所以一般来说和应用开发员关系不大只需要知道他的作用是让g休眠就行goparkunlock(root.lock, reason, traceEvGoBlockSync, 4skipframes)// 从阻塞中被唤醒了开始获取锁没有获取成功继续for循环if s.ticket ! 0 || cansemacquire(addr) {break}}// 依然是阻塞分析不用管if s.releasetime 0 {blockevent(s.releasetime-t0, 3skipframes)}// 释放sudog已经拿到锁就释放了releaseSudog(s) }如何解锁 func semrelease1(addr *uint32, handoff bool, skipframes int) {// 通过addr在全局的sematable的里找对应的semaroot和加锁那边一样root : semtable.rootFor(addr)// 给sema信号1意思是释放锁atomic.Xadd(addr, 1)// 查是否有等待的 Goroutine即等待在锁上的 Goroutine 数量。如果没有等待的 Goroutine则返回不需要唤醒其他 Goroutine。if root.nwait.Load() 0 {return}// 对semaroot里面的lock进行操作上锁防止冲突lockWithRank(root.lock, lockRankRoot)// 再次检查是否有等待的gif root.nwait.Load() 0 {//如果没有等待的g//解锁semaroot的lockunlock(root.lock)return}// 如果有等待的g// 从等待队列里取出一个等待的sudog让他开始他的逻辑s, t0 : root.dequeue(addr)if s ! nil {// 如果treap里面不为空取出sudog成功就把等待数量-1root.nwait.Add(-1)}//解锁semaroot的lockunlock(root.lock)if s ! nil {// 检测用的不用管acquiretime : s.acquiretimeif acquiretime ! 0 {mutexevent(t0-acquiretime, 3skipframes)}if s.ticket ! 0 {throw(corrupted semaphore ticket)}if handoff cansemacquire(addr) {s.ticket 1}readyWithTime(s, 5skipframes)// 当g的m不持有其他锁的时候才允许调度if s.ticket 1 getg().m.locks 0 {// 行协程的切换操作将当前 Goroutine 切换出执行并且将等待的 Goroutine 放入当前的 P 的本地运行队列以便被尽快执行。// 这里会优先分配给本地队列在饥饿状态下切换非常的直接会直接让切换的g使用当前g没有用完的时间片goyield()}} }
http://www.hkea.cn/news/14488170/

相关文章:

  • 惠州惠阳网站建设创意网红蛋糕
  • asp网站建设软件淄博人才网官网首页
  • 线上设计师网站做网站遇上麻烦客
  • 有移动端网站 怎么做app网站会员推广邀请系统
  • 广州正规网站建设哪家好成都建好的网站出租
  • 买入网站建设费的分录帝国怎么做网站
  • 想在网站卖房怎么做软件工程课程设计题目
  • 罗湖城网站建设厦门人才网官网登录
  • 南阳千牛网站建设做亚马逊电商需要投资多少钱
  • 怎么做网站的推广深圳华强北手机城
  • 电商货源网站邢台关键词优化公司
  • 怎么建网站快捷方式网站建设crm
  • 柳州企业网站建设价格公司网站建设和推广
  • 网站维护费用明细电子商务网站建设与管理a
  • 公司手机网站建设价格python语言编程入门
  • 个人网站制作软件哪个好做装修效果图的网站有哪些
  • 专业嵌入式软件开发自己网站做seo
  • 动易网站默认密码郑州北环网站建设培训
  • 最好的网站推广新乡哪里有做网站的
  • 网站即将 模板湛江网站营销
  • 自适应网站怎样做移动适配大城怎么样做网站
  • 中国企业信用网站官网定制微信软件
  • 怎么做公司展示网站wordpress仿家居商城
  • 给网站做app安联建设集团股份公司网站
  • 法制网站建设问卷调查山东手机网站建设
  • 网站首页收录没了wordpress 公司主页
  • 做网站 花时间做网站首页多少钱
  • 台州网站建站服务哪家奿wordpress 目录 伪静态
  • 嘉兴港区建设局网站江西省住房与城乡建设厅网站
  • 大学生做社交网站有哪些天元建设集团有限公司东营分公司