在下面这个例子里, 首先在Erlang Shell里面启动monitor, 监视long_schedule事件. 然后启动一个新进程,进行一些耗时的操作, 可以观察到shell持续不断收到
long_schedule事件,时长从几十毫秒到几百毫秒不等. 如果把lists:seq换成BIF函数,效果也是类似,可是既然BIF函数都有trap机制, 在运行了一部分(几十个 ?)
reduction后会主动放弃CPU,那为什么shell会不断收到long_schedule事件呢 ?
当我们monitor long schedule的时候, 调度器就是简单的记录下每一个Erlang进程被调入调度器的时间(wall clock time)和被调出调度器的时间(wall clock time), 如果这个时间差大于你montior的阈值, 你就会得到long_schedule通知. 基于此,有一些情况可能会导致和你预期的不一样,下面列出了可能的几种导致long_schedule的情形.
# Cause 1 , 当调度器调入一个Erlang进程的时候, 即开始计时, 如果在这个Erlang进程被调出之前, 调度器进程本身作为一个操作系统进程是可能会被其他系统进程抢占的, 这个时候调度器内的Erlang进程(green thread)是没有办法运行的,但是时间仍然在流逝. 当调度器进程本身重新得到CPU的时候, 才有机会继续调度Erlang进程,这个中间的时间是一起计算在内的, 所以这个是一个很常见的导致long schedule的原因, 特别是在一个比较忙的系统上.
#Cause 2, 系统消耗了一些时间, 比如Erlang进程在运行时出现了一个page fault, 需要进行一次swap,调度器会被挂起一段时间直到这个swap完成,这个时间可以是几十毫秒或者更多.
#Cause 3, 当Erlang调度器持有CPU的时候, 系统执行了中断处理程序
1> erlang:system_monitor(self(),[{long_schedule, 10}]).
undefined
2> Pid = spawn(fun()->lists:seq(1,2000000000) end).
<0.65.0>
3>flush().
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,21},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,38},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,17},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,21},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,23},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,31},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,30},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,43},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,53},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,56},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,51},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
Shell got {monitor,<0.65.0>,long_schedule,
[{timeout,81},
{in,{lists,seq_loop,3}},
{out,{lists,seq_loop,3}}]}
##博客仅作个人记录##