golang sudog指的是什么

 更新时间:2024年02月05日 14:29:59   作者:动态一时爽,重构火葬场  
sudog代表在等待队列中的goroutine,比如channel发送接受,由于goroutine和同步对象的关系是多对多,因此需要sudog映射,本文重点介绍golang sudog指的是什么,感兴趣的朋友一起看看吧

sudog代表在等待队列中的goroutine,比如channel发送接受。由于goroutine和同步对象的关系是多对多,因此需要sudog映射

type sudog struct {
  // 指向的goroutine
	g *g
  // 指向前后sudog的指针
	next *sudog
	prev *sudog
  // 指向数据
	elem unsafe.Pointer // data element (may point to stack)
	// The following fields are never accessed concurrently.
	// For channels, waitlink is only accessed by g.
	// For semaphores, all fields (including the ones above)
	// are only accessed when holding a semaRoot lock.
  // 获取时间
	acquiretime int64
  // 释放时间
	releasetime int64
  // 作为队列元素的标识
	ticket      uint32
	// isSelect indicates g is participating in a select, so
	// g.selectDone must be CAS'd to win the wake-up race.
	isSelect bool
	// success indicates whether communication over channel c
	// succeeded. It is true if the goroutine was awoken because a
	// value was delivered over channel c, and false if awoken
	// because c was closed.
	success bool
	parent   *sudog // semaRoot binary tree
	waitlink *sudog // g.waiting list or semaRoot
	waittail *sudog // semaRoot
	c        *hchan // channel
}

acquireSudog()

func acquireSudog() *sudog {
  // 增加m的锁,防止垃圾回收在此期间被调用
	mp := acquirem()
	pp := mp.p.ptr()
 	// 如果本地缓存为空
	if len(pp.sudogcache) == 0 {
		lock(&sched.sudoglock)
    // 从中心缓存迁移至多一半本地缓存容量的缓存项到本地缓存
		for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil {
			s := sched.sudogcache
			sched.sudogcache = s.next
			s.next = nil
			pp.sudogcache = append(pp.sudogcache, s)
		}
		unlock(&sched.sudoglock)
    // 若本地缓存仍为空,则新建缓存项
		if len(pp.sudogcache) == 0 {
			pp.sudogcache = append(pp.sudogcache, new(sudog))
		}
	}
  // 从本地缓存中取出最后一个缓存项返回
	n := len(pp.sudogcache)
	s := pp.sudogcache[n-1]
	pp.sudogcache[n-1] = nil
	pp.sudogcache = pp.sudogcache[:n-1]
	if s.elem != nil {
		throw("acquireSudog: found s.elem != nil in cache")
	}
  // 减少m的锁,允许垃圾回收调用
	releasem(mp)
	return s
}

releaseSudog()

func releaseSudog(s *sudog) {
  // 判断sudog各项数据、状态是否正确
	if s.elem != nil {
		throw("runtime: sudog with non-nil elem")
	}
	if s.isSelect {
		throw("runtime: sudog with non-false isSelect")
	}
	if s.next != nil {
		throw("runtime: sudog with non-nil next")
	}
	if s.prev != nil {
		throw("runtime: sudog with non-nil prev")
	}
	if s.waitlink != nil {
		throw("runtime: sudog with non-nil waitlink")
	}
	if s.c != nil {
		throw("runtime: sudog with non-nil c")
	}
	gp := getg()
	if gp.param != nil {
		throw("runtime: releaseSudog with non-nil gp.param")
	}
	mp := acquirem() // avoid rescheduling to another P
	pp := mp.p.ptr()
  // 如果本地缓存满了,就迁移至多一半容量缓存项到中心缓存
	if len(pp.sudogcache) == cap(pp.sudogcache) {
		// Transfer half of local cache to the central cache.
		var first, last *sudog
		for len(pp.sudogcache) > cap(pp.sudogcache)/2 {
			n := len(pp.sudogcache)
			p := pp.sudogcache[n-1]
			pp.sudogcache[n-1] = nil
			pp.sudogcache = pp.sudogcache[:n-1]
			if first == nil {
				first = p
			} else {
				last.next = p
			}
			last = p
		}
		lock(&sched.sudoglock)
    // 将迁移出来的本地缓存链表直接挂到中心缓存中
		last.next = sched.sudogcache
		sched.sudogcache = first
		unlock(&sched.sudoglock)
	}
  // 将释放的sudog添加到本地缓存
	pp.sudogcache = append(pp.sudogcache, s)
	releasem(mp)
}

到此这篇关于golang sudog是什么?的文章就介绍到这了,更多相关golang sudog内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文带你掌握Golang的反射基础

    一文带你掌握Golang的反射基础

    go的反射是由其标准库中的reflect包实现,该reflect包实现了在运行时进行反射的能力,本篇主要介绍了reflect的常用的几个方法,希望对大家有所帮助
    2023-02-02
  • GoLang socket网络编程传输数据包时进行长度校验的方法

    GoLang socket网络编程传输数据包时进行长度校验的方法

    在GoLang socket网络编程中,为了确保数据交互的稳定性和安全性,通常会通过传输数据的长度进行校验,发送端首先发送数据长度,然后发送数据本体,接收端则根据接收到的数据长度和数据本体进行比较,以此来确认数据是否传输成功
    2024-11-11
  • 详解Golang如何优雅接入多个远程配置中心

    详解Golang如何优雅接入多个远程配置中心

    这篇文章主要为大家为大家介绍了Golang如何优雅接入多个远程配置中心详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • gin正确多次读取http request body内容实现详解

    gin正确多次读取http request body内容实现详解

    这篇文章主要为大家介绍了gin正确多次读取http request body内容实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 解决Golang并发工具Singleflight的问题

    解决Golang并发工具Singleflight的问题

    前段时间在一个项目里使用到了分布式锁进行共享资源的访问限制,后来了解到Golang里还能够使用singleflight对共享资源的访问做限制,于是利用空余时间了解,将知识沉淀下来,并做分享
    2022-05-05
  • Go语言面向对象中的多态你学会了吗

    Go语言面向对象中的多态你学会了吗

    面向对象中的多态(Polymorphism)是指一个对象可以具有多种不同的形态或表现方式,本文将通过一些简单的示例为大家讲解一下多态的实现,需要的可以参考下
    2023-07-07
  • go语言vscode集成开发环境搭建

    go语言vscode集成开发环境搭建

    本文将介绍如何使用VSCode搭建Go语言开发环境,Go语言是一种简洁高效的编程语言,而VSCode是一款轻量级的集成开发环境,二者的结合可以提供良好的开发体验,
    2023-08-08
  • 详解如何在Golang中执行shell命令

    详解如何在Golang中执行shell命令

    这篇文章主要为大家详细介绍了在 golang 中执行 shell 命令的多种方法和场景,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • Go语言中的通道channel详情

    Go语言中的通道channel详情

    这篇文章主要介绍了Go语言中的通道channel,在Go语言中管道类似于一个数据流,每次放入或者取出一部分数据,数据取出后原通道内的数据就删除掉,在linux操作系统中管道会将函数的返回结果作为下一个函数的参数,下文详细内容需要的朋友可以参考下
    2022-02-02
  • Golang排列组合算法问题之全排列实现方法

    Golang排列组合算法问题之全排列实现方法

    这篇文章主要介绍了Golang排列组合算法问题之全排列实现方法,涉及Go语言针对字符串的遍历及排列组合相关操作技巧,需要的朋友可以参考下
    2017-01-01

最新评论