Erlang port driver工作原理

与其说erlang是一个语言运行环境,不如说它是一个虚拟的操作系统环境。在这个操作系统环境下运行着虚拟的erlang process,这些process之间是独立并行运行的,由erlang虚拟机负责调度,就像在真的操作系统中一样。作为虚拟的操作系统,当然少不了对io的处理。这些虚拟的process需要虚拟的io设备来和外界通信。Port在整个erlang环境中就扮演了这个角色。

在erlang中,一个Port其实就代表了一个io句柄。一个process通过open_port打开一个port,然后在这个port上进行读写数据操作,来与这个io句柄进行数据交换。Port被用来抽象所有和erlang虚拟机交互的io对象,比如文件,socket等等,就像unix设计一样。而真正对这些io对象进行操作的,是每个port对应的port driver。

系统与Port Driver的交互
Port driver本身向系统提供一个ErlDriverEntry类型的结构体,其中包含有系统回调函数的指针。每个回调函数都用于在driver中对driver事件进行处理。关于每个回调函数的描述可以参考otp文档。

Erlang虚拟机在默认情况下运行于SMP模式。系统一般会根据处理器数量,启动同样数量的scheduler线程。每个scheduler线程主要负责以下工作:

运行属于本scheduler的process
处理系统io事件
driver在一个scheduler线程中运行,对应以上两个上下文。

所有port相关的bif都运行于process执行上下文中。比如open_port,会立即调用driver的start回调,port_command会调用output回调等等。在处理这些回调时,经常需要一些io处理,比如读写socket或文件。如果我们使用同步的阻塞方法进行读写,将会挂起整个scheduler线程,从而导致所属于这个scheduler的所有工作都被挂起。这是不允许的。所以在driver中处理io时,都会使用非阻塞的方法。

系统通过driver_select接口为driver提供了事件监听机制,来实现非阻塞的io处理。当有io需要操作时,通过driver_select想系统注册可读或者可写事件,然后等待系统回调来最终处理读写。这个回调就是ready_input和ready_output。他们运行于处理系统io事件的上下文中。同样,在这个上下文中也不能阻塞scheduler线程的运行。

系统还为每个port提供了一个driver queue,用来存储异步数据。我们可以通过将待处理的数据加入到driver queue中,等待系统读写事件发生时再进行处理。

如果driver中有耗时的计算需要进行,这也等于阻塞了scheduler线程。为了解决这个问题,系统还提供了driver_async接口。系统在运行scheduler线程的同时,还运行了一个async thread pool,专门用来做异步的计算。我们应该把这样的计算推给async thread pool,然后等待在ready_async中处理结果。erlang本身的zip处理就依赖于async thread pool来进行数据的压缩和解压运算。

综上所述,driver整体基于事件处理和非阻塞模式来处理所有的请求。

关于阻塞
driver的非阻塞模式并不影响虚拟机的阻塞操作。很多高层的函数,比如prim_inet模块中的accept,connect等函数,都通过receive被实现成了阻塞函数。与driver中的阻塞不同,在虚拟机中的阻塞可以被scheduler调度,而不会影响其他的process。

在driver中,还有一个与阻塞相关的功能,就是port busy。driver可以通过set_busy_port将这个port设置成busy状态。如果一个process向busy状态的port发送数据时,这个process就会被挂起,直到port解除busy状态。一般使用这个功能来解决处理能力问题。比如如果socket的数据已经堆积了很多还没有发送出去时,就可以设置busy,让发送process暂时阻塞在发送上面,等待数据发送完成。
————————————————
版权声明:本文为CSDN博主「yuanlin2008」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yuanlin2008/article/details/8244702

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值