go-langs goroutine池只是绿色线程吗?


47

这里评论员提供绿色线程的批评如下:

最初,我是在N:M模型上出售的,这是一种使事件驱动的程序不带回调地狱的方法。您可以编写看起来像是古老的过程代码的代码,但是在其中有一种神奇之处是,只要有东西阻塞,它就会使用用户空间任务切换。听起来不错。问题在于,我们最终要用更多的复杂性来解决复杂性。swapcontext()和family相当困难,其复杂性来自其他意外地方。

突然之间,您被迫编写了一个用户空间调度程序,并猜测编写一个调度程序确实很难做,而要使Linux的调度程序投入大量的精力,这将做得更好。现在,您希望您的日程表将N个绿色线程分配给M个物理线程,因此您不必担心同步。同步带来了性能问题,因此现在就开始您的工作吧,您将遇到一个新的无锁兔子洞。构建正确的高度并发调度程序绝非易事。

另一个批评是在这里

伪造多个线程的单个进程存在很多问题。其中之一是,所有伪造的线程都会在任何页面错误时停止运行。

我的问题是- 去浪的够程(用于默认池)只是绿色的线?如果是这样,他们是否解决了上述批评?

Answers:


67

我只是Go的随便用户,因此,请注意以下事项。

维基百科将绿色线程定义为“由虚拟机(VM)而不是由底层操作系统本地调度的线程”。绿色线程在不依赖任何本机OS功能的情况下模拟多线程环境,并且它们在用户空间而不是内核空间中进行管理,从而使它们可以在不具有本机线程支持的环境中工作。

Go(或更确切地说是两个现有的实现)是仅产生本机代码的语言-它不使用VM。此外,当前运行时实现中的调度程序依赖于OS级线程(即使在GOMAXPROCS = 1时)。因此,我认为谈论Go模式的绿色线程有点滥用。

Go人创造了goroutine术语是为了避免与其他并发机制(例如协程或线程或轻量级进程)混淆。

当然,Go支持M:N线程模型,但它看起来更接近Erlang流程模型,而不是Java绿色线程模型。

这是Go模型相对于绿色线程(在早期JVM中实现的)的一些优点:

  • 对于开发人员而言,可以以透明的方式有效使用多个内核或CPU。使用Go,开发人员应注意并发性。Go运行时将处理并行性。Java绿色线程的实现无法扩展到多个内核或CPU。

  • 系统和C调用对于调度程序而言是非阻塞的(所有系统调用,不仅是在事件循环中支持多路I / O的系统调用)。完成阻塞系统调用后,绿色线程实现可能会阻塞整个过程。

  • 复制或分段堆栈。在Go中,无需为goroutine提供最大堆栈大小。堆栈根据需要递增。结果是,goroutine不需要太多的内存(4KB-8KB),因此可以快乐地产生大量的例程。因此,Goroutine的使用可能很普遍。

现在,解决批评:

  • 使用Go,您不必编写用户空间调度程序:运行时已经提供了它。它是一个复杂的软件,但这是Go开发人员而不是Go用户的问题。对于Go用户来说,其用法是透明的。在Go开发人员中,Dmitri Vyukov是无锁/无等待编程的专家,他似乎对解决调度程序的最终性能问题特别感兴趣。当前的调度程序实现尚不完善,但会有所改善。

  • 同步带来了性能问题和复杂性:Go也是如此。但是请注意,Go模型试图促进并发goroutine中通道的使用和程序的清晰分解,以限制同步复杂性(即通过通信共享数据,而不是共享内存进行通信)。顺便说一下,参考Go实施提供了许多工具来解决性能和并发问题,例如探查器竞速检测器

  • 关于页面错误和“多线程伪造”,请注意Go可以在多个系统线程上安排goroutine。当一个线程由于某种原因(页面错误,阻止系统调用)而被阻止时,它不会阻止其他线程继续调度和运行其他goroutine。现在,页面错误确实会阻塞OS线程,所有goroutine都应该在该线程上进行调度。但是实际上,不应将Go堆内存换出。这在Java中是相同的:垃圾收集的语言不能很好地适应虚拟内存。如果您的程序必须以优美的方式处理页面错误,则可能是因为它必须管理一些堆外内存。在这种情况下,

因此,IMO,goroutines不是绿色线程,Go语言和当前的实现方式大多解决了这些批评。


1
对问题的出色而详尽的回答:)
Tuxdude

1
我喜欢这个答案,但是您对操作系统线程的创建方式有什么参考?
拉斯

1
Go语言的最大缺点之一是,它为每个阻塞的系统调用都创建了一个内核线程!
user1870400

8
请注意,Wikipedia上的“绿色线程”文章已更改为“由运行时库或虚拟机(VM)调度的线程”;这意味着按照该定义,您的答案将不再正确,因为Go运行时会执行调度/管理。我认为将绿色线程定义为与OS线程形成对比的用户空间线程会更有用。然后,是的,goroutines当然是绿色线程。
mknecht

1
第二个@mknecht。这与虚拟机无关,而与运行时有关。Go肯定有一个运行时。(它管理线程模型和垃圾回收)。
蒂姆·哈珀
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.