查看源码 概述
内置机制
Erlang 运行时系统内置了两种互操作机制,即分布式 Erlang、端口 和 NIF。端口的一种变体是链接式驱动。
分布式 Erlang
通过给 Erlang 运行时系统命名,就可以将其变成一个分布式 Erlang 节点。一个分布式 Erlang 节点可以连接到其他节点并监控它们,还可以在其他节点上生成进程。不同节点上的进程之间的消息传递和错误处理是透明的。在分布式 Erlang 系统中可以使用许多有用的 STDLIB 模块。例如,global
,它提供全局名称注册。分布式机制是使用 TCP/IP 套接字实现的。
何时使用: 分布式 Erlang 主要用于 Erlang-Erlang 通信。如果 C 程序实现为一个 C 节点,它也可以用于 Erlang 和 C 之间的通信,请参阅C 和 Java 库。
更多阅读: 《Erlang》书中描述了分布式 Erlang 和一些分布式编程技术。
有关更多信息,请参阅分布式编程。
相关的手册页面如下:
erlang
ERTS 中的手册页面(描述 BIF)global
Kernel 中的手册页面net_adm
Kernel 中的手册页面pg
Kernel 中的手册页面rpc
Kernel 中的手册页面pool
STDLIB 中的手册页面slave
STDLIB 中的手册页面
端口和链接式驱动
从 Erlang 的角度来看,端口提供了与外部世界通信的基本机制。端口为外部程序提供了一个面向字节的接口。创建端口后,Erlang 可以通过发送和接收字节列表或二进制数据(而不是 Erlang 项)与它通信。这意味着程序员可能需要发明一种合适的编码和解码方案。
端口机制的实现取决于平台。对于 UNIX,使用管道,并且假设外部程序从标准输入读取并写入标准输出。外部程序可以用任何编程语言编写,只要它可以处理端口实现的进程间通信机制。
外部程序驻留在与 Erlang 运行时系统不同的操作系统进程中。在某些情况下,这是不可接受的。例如,考虑具有非常严格时间要求的驱动程序。因此,可以按照一定的原则用 C 编写程序,并将其动态链接到 Erlang 运行时系统。这被称为链接式驱动。
何时使用: 端口可用于 Erlang 程序和其他程序在同一台计算机上运行的各种互操作情况。编程相当简单。
链接式驱动程序涉及用 C 编写某些回调函数。这需要非常好的技能,因为代码链接到 Erlang 运行时系统。建议使用 NIF 而不是链接式驱动,因为它们提供了更丰富的功能集,并且可以使用脏调度器进行长时间工作。
警告
有缺陷的链接式驱动程序会导致整个 Erlang 运行时系统内存泄漏、挂起或崩溃。
更多阅读: 《Erlang》书的“杂项”部分描述了端口。附录 E 中描述了链接式驱动程序。
BIF open_port/2
在 ERTS 的 erlang
手册页中进行了文档记录。
对于链接式驱动程序,程序员需要阅读 Kernel 中的 erl_ddll
手册页面。
示例: 端口中的端口示例。
本机实现函数 (NIF)
NIF 提供了一种替代方法,可以使用链接式驱动程序将 C 代码链接到 Erlang 运行时系统。NIF 可以在与操作系统或其他外部库交互时,提供普通 Erlang 函数的 C 实现。
警告
有缺陷的 NIF 会导致整个 Erlang 运行时系统内存泄漏、挂起、崩溃或泄露敏感信息。
何时使用: 由于有缺陷的 NIF 会导致许多与稳定性和安全性相关的问题,因此建议尽可能使用外部端口。如果开销不可接受,则 NIF 是与任何本机代码(无论是 C、C++ 还是 Rust)交互的良好解决方案。
更多阅读: Erlang NIF 库的 API 函数中描述了 NIF。
示例: NIF中的端口示例。
C 和 Java 库
Erl_Interface
端口另一端的程序通常是一个 C 程序。为了帮助 C 程序员,开发了 Erl_Interface 库。
Erlang 外部项格式是将 Erlang 项表示为字节序列(即二进制)的方式。使用以下 BIF 完成两种表示之间的转换:
Binary = term_to_binary(Term)
Term = binary_to_term(Binary)
可以将端口设置为使用二进制文件而不是字节列表。这样就不必发明任何编码/解码方案。Erl_Interface 函数用于解包二进制数据并将其转换为类似于 Erlang 项的结构体。可以以不同的方式操作此结构体,将其转换为 Erlang 外部格式,并发送给 Erlang。
何时使用: 在 C 代码中,与 Erlang 二进制文件结合使用。
更多阅读: 请参阅 Erlang Interface 用户指南、命令参考和库参考。在 Erlang/OTP R5B 和更早的版本中,该信息是 Kernel 应用程序的一部分。
示例: Erl_Interface中的 Erl_Interface 示例。
C 节点
使用 Erl_Interface 函数设置与分布式 Erlang 节点的连接并与之通信的 C 程序称为 C 节点 或隐藏节点。C 节点的主要优点是,从 Erlang 程序员的角度来看,通信非常简单,因为 C 程序的行为类似于分布式 Erlang 节点。
何时使用: C 节点通常可以用于设备处理器(而不是控制处理器),由于内存限制或应用程序特性,或者两者兼而有之,C 比 Erlang 更好。
更多阅读: 请参阅 Erl_Interface 文档的 ei_connect
部分。程序员还需要熟悉 TCP/IP 套接字,请参阅标准协议中的套接字和内置机制中的分布式 Erlang。
示例: C 节点中的 C 节点示例。
Jinterface
在 Erlang/OTP R6B 中,添加了一个类似于 Java 的 Erl_Interface 的库,名为 jinterface。它为 Java 程序提供了一个与 Erlang 节点通信的工具。
标准协议
有时,需要使用标准协议在 Erlang 程序和另一个程序之间进行通信。Erlang/OTP 当前支持 TCP/IP 和 UDP 套接字:如下所示
- SNMP
- HTTP
- IIOP (CORBA)
使用后三者之一需要对协议有充分的了解,并且本教程未涵盖。请分别参阅 SNMP、Inets 和 Orber 应用程序。
套接字
简单来说,面向连接的套接字通信 (TCP/IP) 包括在特定主机上以特定端口号启动的启动器套接字(“服务器”)。知道启动器主机名和端口号的连接器套接字(“客户端”)可以连接到它,并且可以在它们之间发送数据。
无连接的套接字通信 (UDP) 包括在特定主机上以特定端口号启动的启动器套接字和一个向其发送数据的连接器套接字。
有关套接字概念的详细描述,请参阅有关网络编程的合适书籍。建议阅读 W. Richard Stevens 的《UNIX 网络编程,卷 1:网络 API - 套接字和 XTI》,ISBN:013490012X。
在 Erlang/OTP 中,Kernel 中的模块 gen_tcp
和 gen_udp
提供了对 TCP/IP 和 UDP 套接字的访问。两者都易于使用,并且不需要对套接字概念有详细的了解。
何时使用: 用于与 Erlang 程序在同一台计算机上或在另一台计算机上运行的程序。
更多阅读: 请参阅 Kernel 中的 gen_tcp
和 gen_udp
手册页面。
IC 和 CORBA
IC(Erlang IDL 编译器)是一个接口生成器,给定一个 IDL 接口规范,它会自动生成 Erlang、C 或 Java 中的存根代码。请参阅 IC 用户指南和 IC 参考手册。
有关详细信息,请参阅 corba 存储库。