Erlang ERTS的Trap机制的设计及其用途

出处:http://mryufeng.iteye.com/blog/334744

erlang的trap机制在实现中用的很多,在费时的BIF操作中基本上都可以看到。它的实现需要erl vm的配合。它的作用基本上有3个:

1. 把费时操作分阶段做。由于erlang是个软实时系统,一个进程或者bif不能无限制的占用cpu时间。所以erlang的每个进程执行的时候,最多只能执行一定数量的指令.这个是设计方面的目标。实现上也要配套。所以比如md5,list_member查找这种可能耗时的操作都是用trap机制来实现的,也就是说 当进程调度到的时候 执行一定数量的计算 然后把上下文trap起来 放弃执行 等待下一次的调度 来继续计算。

2. 延迟执行,实现上层的决策。 明显的例子是 send操作。 send的时候 节点间可能未连接,所以这个send的操作不能继续,先trap, 然后在下一次的调度的时候 执行节点连接操作,一旦成功 send操作就继续往下执行。对客户来讲这个操作是透明的。他不知道你幕后的这些事情。

3. 主动放弃CPU yield.

erlang设计还是蛮细致的!

PS:涉及到费时操作的BIF有: 
do_bif_utf8_to_list 
ets_delete_1 
spawn_3 
monitor_2 
spawn_link_3 
spawn_opt_1 
send_2 
crc32_1 
adler32_1 
md5_1 
send_3 
build_utf8_return 
build_list_return 
finalize_list_to_list 
do_bif_utf8_to_list 
ets_select_reverse 
ets_match_spec_run_r_3 
re_run_3 
re_exec_trap 
keyfind 
monitor_node_3.

>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
reductions.

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
its timeslice.)

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部分:

  1. erlang函数调用,由于erlang的代码翻译成opcode,由虚拟机执行,所以一次完整的函数调用为一个reduction. 因为erlang的函数通常都是递归执行的,

所以函数体一般很小。

2.   bif的trap机制。简单的说就是bif会执行到大概几个reduction这样的时间片后放弃执行,把当前的执行情况记录下来,然后退出。等下次调度再执行

的时候,会继续之前的位置往下。

3.  IO的调度。 IO也是公平调度的,把IO的处理量换算成reduction,算在宿主进程的时间片里面。

时间: 2024-10-29 19:07:19

Erlang ERTS的Trap机制的设计及其用途的相关文章

让我们聊聊Erlang的Trap机制

在分析erlang:send的bif时候发现了一个BIF_TRAP这一系列宏.参考了Erlang自身的一些描述,这些宏是为了实现一种叫做Trap的机制.Trap机制中将Erlang的代码直接引入了Erts中,可以让C函数直接"使用"这些Erlang的函数. 先让我们思考下为什么Erlang为什么要实现Trap机制?让我先拿最近比较火的Go来说下,Go本身是编译型的和Erlang这种OPCode解释型的性质是不同的.Go的Runtime中很多函数本身也是用C语言实现的,为了胶和Go代码和

自己动手写CPU之第七阶段(5)——流水线暂停机制的设计与实现

将陆续上传本人写的新书<自己动手写CPU>,今天是第28篇,我尽量每周四篇 China-pub的预售地址如下(有目录.内容简介.前言): http://product.china-pub.com/3804025 亚马逊的预售地址如下,欢迎大家围观呵! http://www.amazon.cn/dp/b00mqkrlg8/ref=cm_sw_r_si_dp_5kq8tb1gyhja4 7.5 流水线暂停机制的设计与实现 7.5.1 流水线暂停机制设计 因为OpenMIPS设计乘累加.乘累减.除法

分析erlang热更新实现机制

Joe Armstrong在描述Erlang的设计要求时,就提到了软件维护应该能在不停止系统的情况下进行.在实践中,我们也因为这种不停止服务的热更新获益良多.那么Erlang是如何做到热更新的呢?这就是本文要讨论的问题. 在前面的文章也说到了.erlang VM为每个模块最多保存2份代码,当前版本'current'和旧版本'old',当模块第一次被加载时,代码就是'current'版本.如果有新的代码被加载,'current'版本代码就变成了'old'版本,新的代码就成了'current'版本.

(3)MEF插件系统中通信机制的设计和实现

1.背景 一般的WinForm中通过C#自带的Event机制便能很好的实现事件的注册和分发,但是,在插件系统中却不能这么简单的直接用已有的类来完成.一个插件本不包含另外一个插件,它们均是独立解耦的,实现插件和插件间的通信还需要我们设计出一个事件引擎来完成这个需求. 目前很多高级语言中基本都实现了观察者模式,并进行了自己的包装.比如C#中的delegate和event组合,java awt中的Event和addActionListener组合,Flex中的Event.addEventListene

《深入理解mybatis原理》 MyBatis缓存机制的设计与实现

本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存机制中的方方面面展开讨论. MyBatis将数据缓存设计成两级结构,分为一级缓存.二级缓存: 一级缓存是Session会话级别的缓存,位于表示一次数据库会话的SqlSession对象之中,又被称之为本地缓存.一级缓存是MyBatis内部实现的一个特性,用户不能配置,默认情况下自动支持的缓存,用户没有定制它的权利(不过这也不是绝对的,可以通过开发插件对它进行修改): 二级缓存是A

Javascript继承机制的设计思想

转自:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html 我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain

[strongswan] strongswan是如何实现与xfrm之间的trap机制的

目录 strongswan与xfrm之间的trap机制 0. 1. 前言 2. 描述 2.1 none 2.2 trap 3. 实验与过程 3.1 trap实验 3.2 none实验 4 背景知识 5. 机制分析 5.1 什么是acquire 5.2 那么,什么时候发送acquire消息呢 6. strongswan与xfrm之间的trap机制 0. 你必须同时知道,strongswan,xfrm,strongswan connect trap三个概念. 才有继续读下去的意义. 入门请转到:[T

《深入理解mybatis原理4》 MyBatis缓存机制的设计与实现

<深入理解mybatis原理> MyBatis缓存机制的设计与实现 本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存机制中的方方面面展开讨论. MyBatis将数据缓存设计成两级结构,分为一级缓存.二级缓存:   一级缓存是Session会话级别的缓存,位于表示一次数据库会话的SqlSession对象之中,又被称之为本地缓存.一级缓存是MyBatis内部实现的一个特性,用户不能配置,默认情况下自动支持的缓存,用户没有定制它

Java界面设计的用途

一.Java界面设计的用途: JavaSE(Java Standard Edition)即Java标准版,一般也可以理解作Java桌面版.开发者可以通过JavaSE开发丰富并且强大的具有图形界面的桌面应用程序. Java的图形化界面工具包,可以用于工具类软件开发.管理类软件开发.通用客户端开发.银行客户端软件开发.Eclipse插件开发等方向.在许多知名的大型软件中,都能见到Java的身影,如某些版本的Photoshop.思维导图软件.Eclipse.IDEA开发环境等. 开发者也可以使用Jav