pascal4123 发表于 2013-1-15 02:53:40

erlang-python port 程序

把<Programming Erlang>书上第12章那个erlang-c的例子改编了下,把C程序改写成了python程序。在ubuntu8.04 + erlang5.6.5 + python2.5.2上调试通过。

erlang side: example2.erl

-module(example2).-export().-export().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}) -> ;encode({sum, X, Y}) -> . decode() -> Int.
需要注意的是调用python程序,要使用参数-u。强制标准输入/输出不得有缓存,要立时反应。
python官方文档对-u的解释: Force stdin, stdout and stderr to be totally unbuffered.


python side: example2.py

import sys, osimport structdef recv():    buf = sys.stdin.read(2)    if len(buf) == 2:      (sz, ) = struct.unpack("!h", buf)      payload = sys.stdin.read(sz)      return payload    else:      return Nonedef send(payload):    sz = len(payload)    header= struct.pack("!h", sz)    return sys.stdout.write( header + payload )def twice(arg1):    return 2*arg1def sum(arg1,arg2):    return arg1+arg2def main_loop():    buf = recv()    while buf:      xa = struct.unpack("!%dB" % len(buf), buf)      if xa == 1:            calc_res = twice(xa)      elif xa == 2:            calc_res = sum(xa, xa)      result = struct.pack('!B', calc_res)      send(result)      buf = recv()    return Noneif __name__ == '__main__':    main_loop()
页: [1]
查看完整版本: erlang-python port 程序