简述一下如何从工作线程本地运⾏队列中获取goroutine ?

在Go运行时(runtime)的调度器中,每一个工作线程(也被称为P,processor)都有一个本地运行队列,该队列存储着待运行的goroutine。调度器通过以下步骤从工作线程的本地运行队列中获取(pop)goroutine:

  1. 检查本地运行队列:首先,调度器检查当前工作线程的本地运行队列。如果队列中有goroutine,调度器就取出一个并开始执行。

  2. 偷取其他队列的goroutine:如果当前工作线程的本地运行队列为空,调度器会尝试从其他工作线程的本地运行队列偷取(steal)一半的goroutine。这种偷取策略有助于平衡负载,因为一些工作线程可能比其他线程拥有更多的待运行goroutine。

  3. 从全局运行队列获取goroutine:如果偷取策略失败(也就是其他所有工作线程的本地运行队列都为空),调度器会尝试从全局运行队列中获取goroutine。全局运行队列存储的是那些还未被分配到任何本地运行队列的goroutine。

  4. 阻塞和唤醒:如果所有的运行队列都为空,工作线程就会进入休眠状态。然后,当有新的goroutine被创建或者已存在的goroutine被唤醒时,工作线程会被唤醒并重新开始从运行队列中获取goroutine。

值得注意的是,这些步骤的具体实现可能会因Go语言的版本不同而有所差异。以上描述基于Go 1.14版本的行为。

发表评论

后才能评论