查看源代码 端口和端口驱动程序

关于如何使用端口和端口驱动程序的示例,请参阅互操作性教程。有关提到的 BIF 的信息,请参阅 ERTS 中的模块 erlang

端口

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

创建端口的 Erlang 进程被称为端口的端口所有者,或端口的连接进程。所有与端口的通信都必须通过端口所有者。如果端口所有者终止,则端口也会终止(如果外部程序编写正确,则外部程序也会终止)。

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

端口驱动程序

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

警告

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

有关端口驱动程序的信息,请参阅

端口 BIF

要创建一个端口,请调用 open_port(PortName, PortSettings)。它返回一个端口标识符 Port,作为打开新端口的结果。消息可以像 PID 一样发送和接收到端口标识符。端口标识符也可以使用 link/1 链接,或使用 register/2 在名称下注册。

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

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

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

发送到端口的消息是异步传递的。

更改

在 Erlang/OTP 16 之前,发送到端口的消息是同步传递的。

在以下示例中,Data 必须是一个 I/O 列表。I/O 列表是一个二进制数据,或者是(可能很深的)二进制数据或范围在 0 到 255 之间的整数的列表。

以下消息可以发送到端口

  • {Pid,{command,Data}} - 将 Data 发送到端口。

  • {Pid,close} - 关闭端口。除非端口已关闭,否则当所有缓冲区都已刷新且端口真正关闭时,端口会回复 {Port,closed}

  • {Pid,{connect,NewPid}} - 将 Port 的端口所有者设置为 NewPid。除非端口已关闭,否则端口会向旧端口所有者回复 {Port,connected}。请注意,旧的端口所有者仍然链接到端口,但新的端口所有者没有链接。

以下是可以从端口接收的可能消息。它们被发送到拥有该端口的进程

  • {Port,{data,Data}} - 从外部程序接收到 Data

  • {Port,closed} - 对 Port ! {Pid,close} 的回复。

  • {Port,connected} - 对 Port ! {Pid,{connect,NewPid}} 的回复。

  • {'EXIT',Port,Reason} - 如果端口由于某种原因已终止。

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

还有一些适用于端口驱动程序的其他 BIF