Chinaunix首页 | 论坛 | 博客
  • 博客访问: 101617
  • 博文数量: 18
  • 博客积分: 681
  • 博客等级: 中士
  • 技术积分: 295
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-17 13:33
文章分类
文章存档

2012年(8)

2011年(10)

分类: Python/Ruby

2011-12-03 22:41:29

进程环指的是有n个进程,第1个进程往第2个进程发消息,第2个进程往第3个进程发消息,第n个进程往第1个进程发消息,这样就形成了一个环状结构。

在创建第i个进程的时候,需要知道第i+1个进程的Pid,这样进程i才知道把消息发往哪个进程。因此,可以先创建进程n,然后创建进程n-1,直到创建了进程1,把进程1注册为ring。在创建进程n的时候,把当前创建进程的进程Pid传递给进程n,因为进程n要发送消息至进程1,因此创建进程的进程须把进程n发送的消息转发给进程1。

这样,进程环就构成了一个闭路。当往ring发送一个消息时,会在进程间不断地流转,直到客户端停止消息的发送。

把进程环作为一个黑盒,其向外部提供的几个客户函数(Client Functions)为:
  1. ring:start(N)
  2. ring:send_msg(Msg)
  3. ring:stop()
start生成N个进程,进行相关初始化,如注册第一个进程为ring等。send_msg往进程环发送数据,然后该数据就会在进程环内部流转。最后,客户可以通过stop函数显式地停止进程。

完成的程序源代码如下:
-module(ring).
-export([start/1, send_msg/1, stop/0]).
-export([send/1, start_help/1, start_loop/0]).

start(N) -> call({start, N}).
send_msg(Msg) -> call({send_msg, Msg}).
stop() -> call(stop).

call({start, N}) ->
    spawn(?MODULE, start_help, [N]);
call({send_msg, Msg}) ->
    ring ! {ok, Msg};
call(stop) ->
    ring ! stop.

start_help(N) ->
    register(ring, create_processes(N, self())),
    start_loop().

start_loop() ->
    receive 
{ok, Content} -> ring ! {ok, Content},
start_loop();
stop -> ok
    end.

% `创建N,N-1,...,2进程,其中第N个进程指向当前进程Pid`
% `当创建完第1个进程后,就接收消息,并返回该进程的Pid`
create_processes(N, AfterPid) when N > 1->
    CurrPid = spawn(?MODULE, send, [AfterPid]),
    create_processes(N-1, CurrPid);
create_processes(1, AfterPid) ->
    spawn(?MODULE, send, [AfterPid]).

send(Pid) ->
    receive  
{ok, Content} -> 
   Pid ! {ok, Content},
   io:format("Pid:~p, Msg:~p~n", [self(), Content]),
   send(Pid);
stop -> 
   Pid ! stop
    end.

图 1为初始进程,而图 2为调用ring:start(3)之后创建的进程,可以看到最后创建的进程为第1个进程,而且注册成ring。
图 1
图 2
阅读(1922) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~