erlang 和 外围程序的交互
普通端口方式
外围程序是独立的操作系统程序, 通过标准输入和输出和erlang 交互, 一个在erlang虚拟机中运行, 另一个和虚拟机的运行不在同一个地址空间内。
具体就是erlang vm 通过port -> 标准输入, 然后外围程序读取标准输入,然后处理, 输出到标准输出, 然后erlang vm 接收到标准输出, 即标准输出 -> port。
link 驱动方式
由于都是在同一个地址空间内, 所以erlang虚拟机可以调用驱动的c语言部分。
以gen tcp 为例,
1. 首定指定处理port的driver。 由于socket 本身也是一个port,在gen_tcp:listen的时候, 就会指定一个driver驱动, 在这里应该是”tcp_inet”。 调用序列为 gen_tcp:listen -> inet_tcp:listen -> inet:open -> prim_inet:open 这个函数中就会指定相应的port的driver, 如果是tcp就是 “tcp_inet”。
2. 使用driver。 gen_tcp:recv 的时候 调用的是 prim_inet:recv,之后异步接收, 然后erlang 进程阻塞在recive 原语上。 由此可以知道的是, “tcp_inet” 的driver 实现的recv 是异步的。之后的消息可以通过 driver output写入到 port中, 进而回传给erlang进程 。 ps: “tcp_inet” 的实现是在 inet_drv.c 中。
NIF
可以将erlang函数转变为BIF即内置函数