繁体   English   中英

golang方法将产生goroutines

[英]golang methods that will yield goroutines

据我所知,如果他们太忙,goroutines会阻止其他goroutines运行。 对我来说,这意味着我的应用程序的性能和响应性可能取决于我知道哪些库方法将控制其他goroutine(例如通常是Read()和Write())

有什么方法我可以确切地知道不同的库方法将如何控制其他goroutine,即实际上没有阻止?

有没有办法可以实现一个调用第三方代码的新方法(包括依赖于waitforsingleobject或waitformultipleobjects的异步Win32 API,如findnextchangenotification),并且对Go调度程序表现“不错”? 在这个特定的例子中,系统调用将在完成后发出信号,我需要等到它完成后不会耗尽所有其他goroutine。

是否还有另一个“最佳实践”,如何处理Go中的第三方阻止操作,以便它们不会耗尽其他goroutines?

我假设Go运行时可能在后台线程上内部运行某种IO循环,以便“暂停”阻止goroutine操作,直到它们完成IO。 如果确实如此,那么我认为能够在此基础上构建新的阻塞操作可能会很有用。

Go的调度程序将暂停正在等待系统调用的goroutine,并在系统调用完成时唤醒它们,为您提供同步API来处理异步调用。

阅读有关调度程序如何工作的更多信息。

然而,没有确切的方法可以确定哪个goroutine会被一个接一个地唤醒,或者从一个goroutine直接控制到另一个goroutine - 这就是调度程序的工作。

你关注的是Go中解决的问题,你不必担心它 - 代码了!

编辑:

进一步澄清; 你不应该编码来符合(或更好地利用)Go的调度程序的语义 - 而不是相反。 可能有一些代码技巧可以让你今天略微提升性能,但是调度程序可以并且将来会在任何Go版本中发生变化 - 使你的代码优化变得毫无用处甚至对你起作用。

两种机制可以增强您对此的控制:

  1. runtime.Gosched() - 将控制权交还给调度程序,但当然它对你已经发出的阻塞调用没有帮助。

  2. runtime.LockOSThread()将一个真实的OS线程专用于此goroutine而不是其他,这意味着调度程序中的竞争会更少。 来自文档:

LockOSThread wires the calling goroutine to its current operating system thread. Until the calling goroutine exits or calls UnlockOSThread, it will always execute in that thread, and no other goroutine can.

通过Go 1.1,goroutines只会控制阻塞调用(系统调用,通道读/写,互斥锁等)。 这意味着goroutines理论上可以完全占用CPU,并且不允许调度程序运行。

在Go 1.2中,引入了一个更改以解决此问题:

在以前的版本中,永远循环的goroutine可能会在同一个线程上饿死其他goroutine,这是GOMAXPROCS只提供一个用户线程时的一个严重问题。 在Go 1.2中,部分解决了这个问题:在进入函数时偶尔会调用调度程序。 这意味着任何包含(非内联)函数调用的循环都可以被抢占,允许其他goroutine在同一个线程上运行。

(来源: go1.2发行说明

理论上,仍然可以通过从不调用非内联函数来使goroutine占用CPU,但是这种情况比从未进行阻塞调用的goroutine要少得多,这就是Go 1.2之前的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM