在线文档教程
Erlang 20

15.端口和端口驱动 | 15. Ports and Port Drivers

15 端口和端口驱动程序

提供了如何使用端口和端口驱动程序的示例Interoperability Tutorial。有关提到的BIF的信息,请参阅erlang(3)ERTS中的手册页。

15.1 端口

从Erlang的角度来看,端口提供了与外部世界进行沟通的基本机制。它们为外部程序提供了一个面向字节的接口。当一个端口被创建后,Erlang可以通过发送和接收字节列表(包括二进制文件)与它进行通信。

据说Erlang创建一个端口的过程被称为端口所有者端口连接过程。进出港口的所有通信必须通过港口所有者。如果端口所有者终止,则端口(以及外部程序,如果写入正确)也是如此。

外部程序驻留在另一个OS进程中。默认情况下,它从标准输入(文件描述符0)读取并写入标准输出(文件描述符1)。外部程序将在端口关闭时终止。

15.2端口驱动程序

可以根据某些原则用C语言编写驱动程序,并将其动态链接到Erlang运行时系统。从Erlang程序员的角度来看,链接的驱动程序看起来像一个端口,称为端口驱动程序

警告

错误的端口驱动程序会导致整个Erlang运行时系统泄漏内存,挂起或崩溃。

有关端口驱动程序的信息,请参阅erl_driver(4)ERTS中的手册页,driver_entry(1)ERTS中的手册页,以及erl_ddll(3)内核中的手册页。

15.3端口综合设施

要创建一个端口:

open_port(PortName,PortSettings返回一个端口标识符Port作为打开一个新的Erlang端口的结果。消息可以发送到端口标识符并从端口标识符接收,就像一个pid。端口标识符也可以使用链接/ 1链接,或使用register / 2以名称注册。

PortName通常是一个元组{spawn,Command},其中字符串Command是外部程序的名称。外部程序在Erlang工作区外运行,除非Command找到具有名称的端口驱动程序。如果Command找到,则启动该驱动程序。

PortSettings是端口的设置(选项)列表。该列表通常至少包含一个元组{packet,N},该元组指定在端口和外部程序之间发送的数据前面有一个N字节长度指示符。N的有效值是1,2或4.如果要使用二进制代替字节列表,则binary必须包含该选项。

端口所有者Pid可以Port通过发送和接收消息与端口进行通信。(实际上,任何进程都可以将消息发送到端口,但端口所有者必须在消息中标识)。

从Erlang/OTP R16开始,发送到端口的消息确实是异步传送的。底层实现以前同步向端口传递消息。然而,消息传递始终被记录为异步操作。因此,这不是Erlang程序与端口通信的问题,除非对端口有错误的假设。

在下面的例子中,Data必须是I/O列表。I/O列表是二进制或(可能较深)的二进制或整数列表,范围为0..255:

信息描述
{Pid,{command,Data}}将数据发送到端口。
{PID,close}关闭端口。除非端口已经关闭,否则当所有缓冲区都被刷新并且端口确实关闭时,端口将以{Port,close}进行响应。
{Pid,{connect,NewPid}}设置Portto NewPid的端口所有者。除非端口已关闭,否则端口会以{Port,connected}回复旧端口所有者。请注意,旧的端口所有者仍然与端口相关联,但新的端口所有者不是。

信息描述
{Port,{data,Data}}数据是从外部程序收到的。
{Port,closed}回复 Port ! {Pid,close}。
{Port,connected}回复 Port ! {Pid,{connect,NewPid}}。
{'EXIT',Port,Reason}如果端口由于某种原因而终止。

除了发送和接收消息外,还可以使用一些BIF:

端口BIF描述
port_command(Port,Data)将数据发送到端口。
port_close(Port)关闭端口。
port_connect(Port,NewPid)设置Portto NewPid的端口所有者。旧端口所有者Pid保持链接到端口,如果不需要,必须调用unlink(port)。
erlang:port_info(Port,Item)返回由Item指定的信息。
erlang:ports()返回当前节点上所有端口的列表。

一些额外的BIF适用于端口驱动程序:port_control/3erlang:port_call/3