六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 53|回复: 0

erlang-python port 程序

[复制链接]

升级  0.67%

13

主题

13

主题

13

主题

秀才

Rank: 2

积分
51
 楼主| 发表于 2013-1-15 02:53:40 | 显示全部楼层 |阅读模式
把<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, 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[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 Noneif __name__ == '__main__':    main_loop()
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表