2

Erlang 的Port Drivers

 2 years ago
source link: https://www.ttalk.im/2019/08/erlang-port-drivers.html?amp%3Butm_medium=Atom
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

虽然Erlang已经推出了全新的系统交互方案NIF,但是仍有很多底层系统交互是由Erlang的 另一个系统交互方案Port完成的。Port可以被分为普通Port和Port Drivers,这里将会介绍 Port Divers以及它是什么。

什么是Port

Port可以说是Erlang提供的一种和Erts虚拟机以外世界通信的最基本的方式。Ports为 Erlang提供了双向字节流,让Erlang可以非常好的和外部程序进行通信。默认情况下,外部 程序会在一个全新的OS进程中运行,Erlang通过外部程序的标准输入(文件句柄0)和标准 输出(文件句柄1)进行通讯。创建Port的Erlang进程一般我们将它成为,Port的所有者, 所有和Port的通信都会通过Port所有者进程进行,当所有者进程停止运行了,外部程序也应 该退出。

什么是Port Drivers

当然我们也可以用C或者C++编写一个动态链接库文件(.so或者.dll)让Erlang动态的加载 到虚拟机内,这个动态链接库不会创建新的OS进程,而是直接使用Erlang的进程。但是, Erlang依然使用和Ports,我们将这种内联的Port称为Port Drivers。

Port和Port Drivers的差异

创建方式的不同:Port是通过erlang:open_port直接来创建的,而Port Drivers是先要通过 erl_ddll:load_driver加载到虚拟机内后再通过erlang:open_port完成创建的。

运行方式的不同:Port是运行在Erlang虚拟机外的OS进程和Erlang虚拟机不共享进程,不会 引起Erlang虚拟机内存泄露和崩溃,而Port Drivers和Erlang的虚拟机共享进程,如果处理 不当会引起Erlang虚拟机的崩溃和内存泄露。

性能的差异:Port在创建的时候,beam.smp会使用vfork复制整个进程,这个会导致整个 beam.smp进程阻塞,而Port Drivers只是创建一堆数据,所以性能不用说。

Port Drivers是如何调度的

erl_port_task.c中我们可以找到erts_port_task_schedule函数,正式这个函数将Port Driver调度到Erlang虚拟机上的scheduler上的。erts_port_task_schedule函数会在 erl_check_io的时候被调用。从这些代码中我们可以观察到:

  1. Port Drivers并不会一直放在ErtsPortTaskSched当中。
  2. Erlang的Port Drivers只有在Erlang进程通过erlang:controlerlang:command函数发 送命令时,会将Port放入RunQueue。
  3. Erlang的Port Drivers向Erlang虚拟机注册IO任务,erts会在erl_check_io放到 RunQueue中。

Port Drivers为什么这么实现和调度

  1. Erlang的虚拟机的调度器是一个软实时的调度器,它在调度Erlang进程的时候会为 Erlang进程分配固定的reduction。Erlang虚拟机规定了每个Erlang的操作的reduction 的数量,当Erlang进程的reduction减少到位0的时候,将进行Erlang进程切换。
  2. Erlang的虚拟机要保证调度器是无阻塞的,才能达到软实时调度。通过reduction机制, 可以保证不执行IO操作的Erlang进程达到无阻塞。为了让IO操作不阻塞调度器,那么就 必须让IO操作变成一种任务。
  3. Port Drivers很多时候,都是为了完成外部通信操作或者IO操作。因此Erlang将所有的 IO操作都和事件驱动进行关联,当不能直接向事件驱动器的注册的IO操作则通过异步线 程模拟成IO事件。这样就可以将IO操作变成IO任务,这样就如同无阻塞的操作一样。
  4. Port Drivers可以说是Erlang虚拟机对IO操作的高级抽象,这样就将复杂的外部世界和 非IO操作尽最大可能的隔离开了。不但可大大减少代码量,同时也提高了平台的兼容性。 最终Erlang的虚拟机内,将所有的IO操作和计算抽象成了执行队列上的一个又一个任务, 方便运行在多核心上的调度器进行调度和任务密取,提高并发。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK