2011-05-04 39 views
4

可能重复:
Technically why is processes in Erlang more efficient than OS threads?究竟是什么让Erlang进程,绿色线程,协程比内核线程“更轻”?上下文切换很重要吗?

在任何时间Erlang进程或绿色线程或协程被提及,它们总是相比内核线程时描述为“重量轻”。通常给出的原因是内核线程涉及缓慢的上下文切换。

但究竟是关于上下文切换是慢?与在用户空间切换绿色线程相比,速度有多慢?

是上下文切换主(仅?),其占如Nignx和多处理程序如Apache事件驱动程序之间在性能和内存消耗的差异因子?

+0

+1对于一个写得很好的问题,即使是重复的。 – 2011-05-04 04:03:11

回答

11

先占式,单片式,多任务操作系统上的上下文切换涉及两条路径中的一条,或者通过某个系统服务调用(睡眠,互斥锁获取,等待事件,阻塞I/O)一个中断和调度程序决定交换正在运行的任务。

当任务被调度交换,几个重量级的事情发生了:

  • 所有的动作发生,因为操作系统内核的一部分,在高级别特权运行。每一个行动都被选中(或应该),以确保由调度做出的决定不授予任务的任何其他权限(认为本地root权限)
  • 用户模式进程的地址空间被交换。这会导致内存管理器与页表布局混乱,并将新的目录库加载到控制寄存器中。
  • 这也意味着保存在CPU缓存中的数据可能被击落并清除。如果你的任务刚刚访问了一堆常用的东西,这将吸,然后上下文切换和“迷失”是
  • (在接下来的访问,将[可能]已被再次主存储器中取出)取决于你如何陷阱进入内核,然后你需要捕获内核的OUT。例如,如果您进行系统调用,CPU将通过一组非常精确的步骤转换为在内核中运行的代码,然后在退出时展开这些步骤。这些步骤比在程序中调用另一个模块的函数更复杂,因此需要更多时间。

绿色线程任务是非常简单的,按照我的理解。用户模式调度程序指示协程运行,直到协程收益。在上面的一些区别是:

  • 协程的调度没有发生在内核模式下,的确调度绿色线程通常并不需要涉及任何操作系统的服务,或任何阻止操作系统服务。所有这些都可以在没有任何上下文切换或任何用户/内核转换的情况下发生。
  • 绿色线程没有抢先调度,甚至通过绿色线程管理器抢占可言,他们被安排合作的态度。这是好的和坏的,但写得很好的例程,一般都很好。每个任务都会完成它需要做的事情,然后将其捕获回调度程序,但没有任何上下文交换开销。
  • 绿线程共享其地址空间(据我所知)。上下文切换不会交换地址空间。堆栈(据我所知)被交换,但是这些堆栈由调度器管理,并且交换堆栈也是一个简单的写入寄存器。交换堆栈也是非优先操作。

总之,用户模式中的上下文切换涉及一些库调用和写入堆栈指针寄存器。内核模式中的上下文切换涉及中断,用户/内核转换以及系统级别的行为,如地址空间状态更改和缓存刷新。

+0

在敏感的体系结构(具有物理地址缓存的体系结构)上,高速缓存通常不会在上下文切换上清除。 – caf 2011-05-06 11:43:45

+0

Erlang进程确实使用**预先计划**。 Erlang VM管理上下文切换。这是非常重要的,因为长时间运行的进程不能以这种方式阻止其他进程。这是一个Erlang功能。 Erlang还为每个进程执行垃圾收集,而Erlang进程很小。所有这些使得Erlang成为实时系统的合适语言。 – Jonas 2011-06-02 07:17:26