把<Programming Erlang>书上第12章那个erlang-c的例子改编了下,把C程序改写成了python程序。在ubuntu8.04 + erlang5.6.5 + python2.5.2上调试通过。
erlang side: example2.erl
-module(example2).
-export([start/0, stop/0]).
-export([twice/1, sum/2]).
start() ->
spawn(fun() ->
register(example1, self()),
process_flag(trap_exit, true),
Port = open_port({spawn, "python -u ./example2.py"}, [{packet, 2}]),
loop(Port)
end).
stop() ->
example1 ! stop.
twice(X) -> call_port({twice, X}).
sum(X,Y) -> call_port({sum, X, Y}).
call_port(Msg) ->
example1 ! {call, self(), Msg},
receive
{example1, Result} ->
Result
end.
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {example1, decode(Data)}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
exit({port_terminated,Reason})
end.
encode({twice, X}) -> [1, X];
encode({sum, X, Y}) -> [2, X, Y].
decode([Int]) -> Int.
需要注意的是调用python程序,要使用参数-u。强制标准输入/输出不得有缓存,要立时反应。
python官方文档对-u的解释: Force stdin, stdout and stderr to be totally unbuffered.
python side: example2.py
import sys, os
import struct
def recv():
buf = sys.stdin.read(2)
if len(buf) == 2:
(sz, ) = struct.unpack("!h", buf)
payload = sys.stdin.read(sz)
return payload
else:
return None
def send(payload):
sz = len(payload)
header= struct.pack("!h", sz)
return sys.stdout.write( header + payload )
def twice(arg1):
return 2*arg1
def sum(arg1,arg2):
return arg1+arg2
def main_loop():
buf = recv()
while buf:
xa = struct.unpack("!%dB" % len(buf), buf)
if xa[0] == 1:
calc_res = twice(xa[1])
elif xa[0] == 2:
calc_res = sum(xa[1], xa[2])
result = struct.pack('!B', calc_res)
send(result)
buf = recv()
return None
if __name__ == '__main__':
main_loop()
分享到:
相关推荐
erlang-port-howto 如何创建一个Erlang端口。 端口是允许Erlang程序与外部程序进行交互的方法之一。 在本教程中,示例中使用了一个小的python程序。 在阅读本教程之前,您应该熟悉基本的Erlang。 教程文件位于lib/...
它打开一个端口(`open_port`),该端口通过`spawn`选项运行Python解释器,并传递一个Python脚本的路径(在这个例子中是`/home/freefis/Desktop/town.py`)。`stream`和`{line, 1024}`选项确保数据以行的形式交互,...
- Erlang - JavaScript - Python - PHP - Ruby - Java - Perl 这些驱动程序使得开发者能够在各种不同的环境中使用MongoDB。 **1.3 生产环境部署** MongoDB已经在众多生产环境中成功部署,具体案例和经验可以参考...
4. **生产者与消费者**: 使用各种编程语言(如Python、Java、JavaScript等)的RabbitMQ客户端库,编写生产者和消费者代码,实现消息的发送和接收。 **总结** Erlang和RabbitMQ的组合为开发者提供了一种强大、可靠...
GenServer 是 Elixir 中用于处理状态管理和异步通信的模块,而 Port 则是 Erlang/VM 用来与外部进程(如操作系统进程或其他语言的程序)交互的机制。Exos 的设计目标是为开发者提供一种安全、方便的方式来调用 Node....
1. **Python版本**:确保服务器上已安装Python 2.6或2.7版本。 2. **网络连接**:保证服务器能够顺畅地连接到互联网。 3. **内存需求**:预留充足的内存空间用于Ansible Tower的运行。 4. **安装用户**:推荐使用...
- **跨平台兼容性**:MongoDB可以在多种操作系统上运行,包括但不限于OS X、Linux和Windows等,并为多种编程语言提供了官方驱动程序,如Python、PHP、Ruby、Java、C#、JavaScript、Perl和C++等,甚至还有对Erlang和...
兼容win、mac等操作系统,该工具可以说很大程度上弥补了memcached这类key/value存储的不足,为Java、C/C++、C#、PHP、JavaScript、Perl、Object-C、Python、Ruby、Erlang等开发语言提供了便利的客户端。 【软件特点...
在IT行业中,消息队列(Message Queue)是用于应用程序间异步通信的重要工具,而RabbitMQ作为一款开源的消息代理和队列服务器,被广泛应用于Java、Python等多语言环境中。Spring Boot则是一款用于简化Spring应用初始...
EMQ X的插件系统允许开发者通过Erlang/OTP编写插件,实现自定义功能,如数据转发、消息过滤等。插件配置文件通常位于"etc\plugins"目录下。 9. **监控与报警** EMQ X支持Prometheus和Grafana集成,用于性能监控和...
Redis 支持多种语言,诸如 Ruby, Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java, Scala, Clojure 等。 主-从复制: Redis 支持简单而快速的主-从复制。官方提供了一个数据,Slave 在 21 秒即完成了...