`
erwinbarton
  • 浏览: 12271 次
  • 性别: Icon_minigender_1
  • 来自: 佛山
社区版块
存档分类
最新评论

飞机空中换引擎之cool之零

阅读更多
飞机空中换引擎之cool之零
11年12月2日 下午 11:03:43

**严重声明:该例子来自《Erlang程序设计》16.1
这是热切换代码的简单例子...像erlang或java等的带vm动态语言的话,
随便切换运行中的代码是一件极其容易的事情。
但像c语言的这种静态语言的话只能通过动态装载so的方式来干活了。
写语言的语言,必须是可以随心欲为了...

hot_code.erl
-module(hot_code).
-export([start/2, stop/1, rpc/2, swap_code/2]).

start(Name, Mod)->
    register(Name,
     spawn(fun()->
   loop(Name, Mod, Mod:init())
   end)).
stop(Name)->
    rpc(Name, {stop}).

swap_code(Name, Mod)->
    rpc(Name, {swap_code, Mod}).

rpc(Name, Request)->
    Name! {self(), Request},
    receive
{Name, Response}->
    Response
    end.

loop(Name, Mod, OldState)->
    receive
{From, {swap_code, NewCallBackMod}}->
    From! {Name, ack},
    loop(Name, NewCallBackMod, OldState);
{From, {stop}} ->
    From! {Name, ack};
{From, Request} ->
    {Response, NewState} = Mod:handle(Request, OldState),
    From! {Name, Response},
    loop(Name, Mod, NewState)
    end.

name_server1
-module(name_server1).
-export([init/0, add/2, whereis/1, handle/2]).
-import(hot_code, [rpc/2]).

add(Name, Place)->
    rpc(name_server, {add, Name, Place}).
whereis(Name)->
    rpc(name_server, {whereis, Name}).

init()->
    dict:new().


handle({add, Name, Place}, Dict)->
    {ok, dict:store(Name, Place, Dict)};
handle({whereis, Name}, Dict) ->
    {dict:find(Name, Dict), Dict}.

name_server3
-module(name_server3).
-export([init/0, add/2, whereis/1, handle/2, list_all/0]).
-import(hot_code, [rpc/2]).

add(Name, Place)->
    rpc(name_server, {add, Name, Place}).
whereis(Name)->
    rpc(name_server, {whereis, Name}).
list_all()->
    rpc(name_server, {list_all}).

init()->
    dict:new().

handle({add, Name, Place}, Dict)->
    io:format("added ~p~n", [Name]),
    {ok, dict:store(Name, Place, Dict)};
handle({whereis, Name}, Dict) ->
    io:format("query ~p~n", [Name]),
    {dict:find(Name, Dict), Dict};
handle({list_all}, Dict)->
    io:format("list all~n"),
    {dict:fetch_keys(Dict), Dict}.

Run command in erl:
c(hot_code).
c(name_server1).
hot_code:start(name_server, name_server1).
name_server1:add(joe, “usa”).
name_server1:whereis(joe).
hot_code:swap_code(name_server, name_server3).
name_server3:add(mary, “canada”).
name_server3:list_all().

hot_code 是框架, name_server1 是第一个模块...
start时把第一个版本的name_server register到name_server上,
然后正常的增查服务;
之后,有个无聊的家伙写了版本3的name_server3,多添加了一个功能,
list_all(),这时只需要命令框架swap_code一下。
这样,register到name_server上的代码模块是name_server3,
(在loop()的一次迭代后替换了...如果多个操作并发到loop()??)
然后飞机...换了引擎了。

//++++++++++++++++++++++++++++++
c/java 也可以做到这个挺逗的功能。
c语言,dyn_load so模块
framework.cpp
msg_queue q_cmd;
msg_queue q_resp;
load(const char *fname);
start(void *handle, const char *fname){
handle = load(fname);
loop(...);
}
swap_code(const char *fname){
push(q_cmd, “{swap, fname}”)
}
loop(...){
while( true){
msg = pop(q_cmd);
switch(msg){
“{swap, fname}”: handle=load(fname); push(q_resp, “ack”); break;
“{call, func_name, ...}”: ret = handle:handle(“func_name”, ...);  push(q_resp, ret); break;
}
}
}

name_server1.cpp
func_a(...);
func_b(...);
handle(“func_name”, args){
switch(“func_name”){
“a”: func_a(args);
“b”: func_b(args);
}
}

Java...just like RPC, and reflect mechanism …

To Be Stupid(TBS)...
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics