1. 把费时操作分阶段做。由于erlang是个软实时系统，一个进程或者bif不能无限制的占用cpu时间。所以erlang的每个进程执行的时候，最多只能执行一定数量的指令.这个是设计方面的目标。实现上也要配套。所以比如md5,list_member查找这种可能耗时的操作都是用trap机制来实现的，也就是说 当进程调度到的时候 执行一定数量的计算 然后把上下文trap起来 放弃执行 等待下一次的调度 来继续计算。
2. 延迟执行，实现上层的决策。 明显的例子是 send操作。 send的时候 节点间可能未连接，所以这个send的操作不能继续，先trap, 然后在下一次的调度的时候 执行节点连接操作，一旦成功 send操作就继续往下执行。对客户来讲这个操作是透明的。他不知道你幕后的这些事情。
3. 主动放弃CPU yield.
>Can someone tell me how Erlang processes are scheduled? I‘m doing
>some quick research into real-time languages, I know Erlang is only
>a `soft‘ real-time system, but just how soft is it? Does Erlang make
>any attempt at all to meet real-time deadlines other than making
>context switches very fast and efficient?
Erlang processes are currently scheduled on a reduction count basis.
One reduction is roughly equivalent to a function call.
A process is allowed to run until it pauses to wait for input (a
message from some other process) or until it has executed 1000
There are functions to slightly optimize the scheduling of a process
(yield(), bump_reductions(N)), but they are only meant for very
restricted use, and may be removed if the scheduler changes.
A process waiting for a message will be re-scheduled as soon as there
is something new in the message queue, or as soon as the receive timer
(receive ... after Time -> ... end) expires. It will then be put last
in the appropriate queue.
Erlang has 4 scheduler queues (priorities):
‘max‘, ‘high‘, ‘normal‘, and ‘low‘.
‘max‘ and ‘high‘ are strict. This means that the scheduler will
first look at the ‘max‘ queue and run processes there until the
queue is empty; then it will do the same for the ‘high‘ queue.
‘normal‘ and ‘low‘ are fair priorities. Assuming no processes at
levels ‘max‘ and ‘high‘, the scheduler will run ‘normal‘ processes
until the queue is empty, or until it has executed a total of 8000
reductions (8*Max_Process_Reds); then it will execute one ‘low‘
priority process, if there is one ready to run.
The relationship between ‘normal‘ and ‘low‘ introduces a risk of
priority inversion. If you have hundreds of (active) ‘normal‘
processes, and only a few ‘low‘, the ‘low‘ processes will actually get
higher priority than the ‘normal‘ processes.
There was an experimental version of a multi-pro Erlang runtime
system. It supported Erlang processes as OS threads, and then used the
scheduling and prority levels of the underlying OS.
One important thing to note about the scheduling is that from the
programmer‘s perspective, the following three things are invariant:
- scheduling is preemptive（抢占的）.
- a process is suspended if it enters a receive statement, and there
is no matching message in the message queue.
- if a receive timer expires, the process is rescheduled.
The Erlang Processor, for example, will most likely schedule based on
CPU cycles (essentially a time-based scheduler). It may also have
multiple thread pools, allowing it to context switch within one
clock cycle to another process if the active process has to e.g.
wait for memory.
In a runtime environment that supports it, it should be possible
to also have erlang processes at interrupt priority (meaning that
they will be allowed to run as soon as there is something for them
to do -- not having to wait until a ‘normal‘ priority process finishes
Erlang schedulers are based on reduction counting as a method for measuring execution time.
A reduction is roughly equivalent to a function call. Since each function call may take a different amount of time,
the actual periods are not the same between different reductions.
When a process is scheduled to run, it is assigned a number of reductions that it is allowed to execute
(by default 2000 reductions in R13B04).
The process can execute until it consumes all its reduction quantum or pauses to wait for a message.
A process waiting for a message is rescheduled when a new message comes or a timer expires.
Rescheduled or new processes are put to the end of corresponding run queues.
Suspended (blocked) processes are not stored in the run queues
3. IO的调度。 IO也是公平调度的，把IO的处理量换算成reduction，算在宿主进程的时间片里面。