Erlang 中进程的两种调用方式
????????? 一个常见的情况: supervisor 下启动了N个子进程,如何访问这些子进程?
????????? 一般可以通过两种方式:
????????? 1.通过PID
???????????? 所有的子进程在创建完成后都会有相应的PID,将这些个PID存到本地的表中,需要时通过PID去访问进程。
????????? 2.通过进程名
???????????? 在注册一个进程的时候为其指定相应的名称,需要时通过进程名访问进程。
?
???????? 下面为一个简单的例子:
?
????????? 建立一个supervisor ,采用simple_one_for_one 的启动策略:
-module(superMan).-behaviour(supervisor).-export([start_sup/0,open_wc/1]).-export([ init/1 ]).-define(SERVER, ?MODULE).start_sup()->supervisor:start_link({local,superMan}, ?MODULE, []).init([]) -> AChild = {wcroom, {thewc,start_link,[]}, temporary, 2000, worker, [thewc]}, {ok, {{simple_one_for_one,0,1}, [AChild]}}.open_wc(Num)->supervisor:start_child(superMan,[Num]).?
??? 子进程的模块定义如下:
-module(thewc).-behaviour(gen_server).-export([lashi/2,start_link/1]).-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).-record(state, {num}).start_link(Num)-> gen_server:start_link({local,list_to_atom(integer_to_list(Num))},?MODULE,[Num],[]).init([Num]) -> {ok, #state{num=Num}}.handle_call({lashi,Name}, From, State) ->#state{num=Num}=State, io:format("man ~p is lashing in wc~p",[Name,Num]), {reply, ok, State};handle_call(Request, From, State) -> Reply = ok, {reply, Reply, State}.handle_cast(Msg, State) -> {noreply, State}.handle_info(Info, State) -> {noreply, State}.terminate(Reason, State) -> ok.code_change(OldVsn, State, Extra) -> {ok, State}.lashi({pid,Ref},Name)->gen_server:call(Ref, {lashi,Name});lashi(Num,Name)->gen_server:call(list_to_atom(integer_to_list(Num)), {lashi,Name}).?????????? 测试方法如下:
start()->{ok,Pid}=superMan:start_sup(),unlink(Pid),{ok,Pid1}=superMan:open_wc(1),thewc:lashi({pid,Pid1}, "wang"),{ok,Pid2}=superMan:open_wc(2),thewc:lashi(2, "zhang").?
???????? 测试结果如下:
man "wang" is lashing in wc1man "zhang" is lashing in wc2ok
?
???????? 需要注意的是:在gen_server:call(Module,Args) 的时候,如果要调用的进程是注册在本地的,则Module 直接为进程名对应的Atom 值。只有这个进程注册为gloable 时才需要指定Module 为{gloable,Module},否则会报nodedown异常。
?
?
?