Erlang socket 工作原理

Erlang利用其对并发的原生支持,成为构建网络服务器的理想选择。本文深入探讨了Erlang如何处理socket连接,介绍了PortDriver的工作原理,以及如何与erlang的并发机制结合。详细讲解了erlang的io模型,包括portdriver的非阻塞性质,以及系统事件分派器在Linux上的epoll实现。此外,还分析了系统调用、数据返回机制,以及OTP库中socket功能的封装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于对并发的原生支持,erlang在很多时候被用来构建网络服务器(socket server, http server...)的底层,处理大量的并发连接。理解erlang在底层如何处理socket,以及如何与自己的并发机制结合,对于使用erlang来构建网络服务至关重要。

erlang的对socket的处理被分为两个部分。

Port Driver的中的处理
基本的io模型
在《Erlang Port Driver工作原理》中,已经对port driver的运行机制做了初步的介绍。在erlang中,一个socket被表示为一个port。socket的port driver的实现全部在OTP/erts/emulator/drivers/common/inet_drv.c中。Port driver遵循非阻塞的原则,不会在处理socket io时阻塞scheduler线程。所有需要阻塞的操作,比如accept,connect,send等等,都是通过driver_select向系统的事件分派器注册可读写事件,等待系统回调后进行处理。

系统的事件分派器在linux上使用epoll实现。多个scheduler线程并发在这个分派器上监听系统的io事件,这就是整个erlang虚拟机的io处理模型。这与使用C++的ACE Reactor模式基本上是一致的。

所以理论上,在不考虑scheduler线程对于runqueue中process运行的消耗,erlang虚拟机处理io的效率应该与多线程驱动的ACE Reactor(epoll)模型基本一致。

系统调用和数据返回
socket是port,所以当然应该使用port相关的bif与port进行交互。

使用socket发送数据是通过调用port_command或者使用"!"操作符实现的。如果不能立即发送,消息会缓存到driver queue中,等待系统的可写事件。在driver中有控制driver queue的高低水位(watermark),当累积的发送数据大于高水位时,driver会被设置成busy状态,直到driver queue中的数据低于地水位才解除。如果向一个busy状态的socket发送数据,将会造成port_command的阻塞,从而挂起发送process,直到busy状态解除后退出。

所有其他的命令(open, shutdown, listen, accept, connect...)都作为socket port的控制命令,通过port_control发送给driver。所有的port_control命令都被实现为异步模式,会立即返回。比如connect命令会立即返回,而不会等待connect成功。connect的结果是通过process本身的消息队列返回的。需要注意的是,结果会返回给命令的调用者process,也就是caller,而不是port的owner process,这不同于接收数据都是给owner process。也就是说我们在任何process中调用port_control来对socket发出命令,都可以在本process的消息队列中得到结果。

Erlang OTP中的封装
这里的otp指的是全部用erlang本身实现的otp库。

在otp中,socket的功能是通过prim_inet.erl模块向外提供访问的。prim_inet在本身原始的port命令上进行封装,将与socket port的消息交互封装成了函数(connect, accept...)。而prim_inet一个更重要的工作,就是将port层次基于消息的异步交互机制,通过在发送消息后立即receive结果,挂起当前process,变成了阻塞的同步交互机制。比如prim_inet中的connect函数,就是通过调用port_control向driver发送INET_REQ_CONNECT消息后,立即receive结果并将结果返回来实现一个阻塞的connect语义。所以,erlang中对socket的阻塞操作都是在process层面实现的,这样的阻塞可以被scheduler调度。
————————————————
版权声明:本文为优快云博主「yuanlin2008」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/yuanlin2008/article/details/8277404

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值