Erlang并发机制 –进程调度

Erlang调度器主要完成对Erlang进程的调度,它是Erlang实现软件实时和进程之间公平使用CPU的关键。Erlang运行时,有4种任务须要被调度:进程,PortLinked-in driver,Erlang虚拟机的系统级活动。html

 

Erlang调度器主要有如下特色:算法

1. 进程调度运行在用户空间 :Erlang进程不一样于操做系统进程,Erlang的进程调度也跟操做系统彻底没有关系,是由Erlang虚拟机来完成的;编程

2. 调度是抢占式的:每个进程在建立时,都会分配一个固定数目的reduction(R15B中,这个数量默认值是2000),每一次操做(函数调用),reduction就会减小,当这个数量减小到0时或者进程没有匹配的消息时,抢占就会发生(无视优先级);函数

3. 每一个进程公平的使用CPU:每一个进程分配相同数量的reduction,能够保证进程能够公平的(不是相等的)使用CPU资源性能

4. 调度器保证软实时性:Erlang中的进程有优先级,调度器能够保证在下一次调度发生时,高优先级的进程能够优先获得执行。spa

 

Reduction操作系统

受操做系统中基于时间片调度算法的影响,一开始知道有reduction这个概念时,一直想搞清楚这个reduction到底对应多长的绝对时间,不过,从Erlang自己对reduction的使用来看,彻底没有必要纠结这个问题。《Erlang编程指南》一书中对reduction的说明以下:线程

程序中的每个命令,不管它是一个函数调用,仍是一个算术操做,或者内置orm

函数,都会分配必定数量的reduction。虚拟机使用这个值来衡量一个进程的活htm

动水平。

看到这个定义的第一反应是,若是一个函数调用的执行时间很长怎么办?那不是一个进程会长时间的占用资源?Erlang对这个问题的答案是Trap机制,上一篇中有提到过,它的其中一个功能就是把费时的操做分阶段作,好比lists:reverser和lists:member可能会根据输入的不一样会有很大的变化,因此就会使用到Trap机制:先执行一段时间,再Trap,而后再次调度到的时候再继续执行。

 

SMP支持

从R11B(2006)Erlang开始支持SMP(Symmetrical Multi Processor,也就是多核)。Erlang对SMP的支持分为如下几个阶段:

1). 单调度器、单运行队列:调度器运行在虚拟机主进程中的一个线程中,从单个任务队列中获取运行进程,由于只有一个线程,因此对运行队列的访问不须要锁;

2). 多调度器、单运行队列:调度器的个数能够自定义(参见erl命令的+S参数,默认数量同CPU核的数量),每一个调度器运行在一个线程中,可是只有一个运行队列,全部调度器都从同一个运行队列获取运行进程,因此会涉及到共享资源的访问,须要用到锁。

3). 多调度器、多运行队列:每一个调度器都绑定有一个运行队列,每一个调度器都从各自的运行队列中获取运行进程。相比单运行队列,多运行队列会减小锁冲突,提升性能,可是,由于涉及到多运行队列,就必须要考虑负载问题:若是一个调度器很忙,另外一个很闲,那怎么办?Erlang虚拟机存在一个任务迁移的逻辑,来保证各个调度器达到平衡。

 

进程优先级

Erlang进程有四种优先级:max, high, normal, low(max只在Erlang运行时系统内部使用,普通进程不能使用)。Erlang运行时有两个运行队列对应着max和high优先级的运行任务,normal和low在同一个队列中。

调度器在调度发生时,老是首先查看具体max优先级的进程队列,若是队列中有能够进行的进程,就会运行,直到这个队列为空。而后会对high优先级的进程队列作一样的操做(在SMP环境,由于同时有几个调度器,因此在同一时间,可能会有不一样优先级的任务在同时运行;但在同一个调度器中,同一时间,确定是高优先级的任务优先运行)。

普通进程在建立时,通常是normal优先级。normal和low优先级的进程只有在系统中没有max和high优先级的进程可运行时才会被调度到。一般状况下,normal和low优先级的进程交替执行,low优先级得到CPU资源相对更少(通常状况下):low优先级的任务只有在运行了normal优先级任务特定次数后(在R15B中,这个数字是8)才会被调度到(也就是说只有在调度了8个normal优先级的进程后,low优先级的进程才会被调度到,即便low优先级的进程比normal优先级的进程更早进入调度队列,这种机制可能会引发优先级反转:假如你有成千上万的活动normal进程,而只有几个low优先级进程,那么相比normal进程,low优先级可能会得到更多的CPU资源)。

 

调度算法的实现见[$OTP_SRC/erts/emulator/beam/erl_process.c --> schedule],下面的图片是算法流程图,来源于这篇论文:Characterizing the Scalability of Erlang VM on Many-core Processors

相关文章
相关标签/搜索