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

2012年(8)

2011年(10)

分类: Python/Ruby

2011-12-22 18:45:29

Erlang的变量不可变,这就意味着不能使用变量来实现计数器,然而可以用一个进程来模拟一个计数器。即使用一个loop循环来模拟一个状态,当接受到add消息时,loop的参数就+1,这样就模拟了一个状态,详细代码如下:
-module(counter).
-export([start/1,add/1,value/1]).
-export([init/1]).

start(InitCount) ->
    spawn_link(?MODULE, init, [InitCount]).

add(Name) -> call({add, Name}).
value(Name) -> call({value, Name}).

call({Request, Name}) ->
    Name ! {request, Request, self()},
    receive
{reply, Reply} -> Reply
    end.

init(Count) ->
    receive
{request, add, From} ->
   reply(From, Count+1),
   init(Count+1);
{request, value, From} ->
   reply(From, Count),
   init(Count)
    end.

reply(From, Count) ->
    From ! {reply, Count}.

  1. 15> Counter = counter:start(3).
  2. <0.62.0>
  3. 16> counter:value(Counter).
  4. 3
  5. 17> counter:add(Counter).
  6. 4
  7. 18> counter:add(Counter).
  8. 5
上面为计数器的使用方法,Counter相当于计数器的名字,实际上为计数器的Pid,计数器+1的操作都是通过向该进程发送消息来实现的。上述的代码中没有用到register方法,意味着不会与其它进程使用的计数器发生冲突。

这里的一个问题是,进程的状态是保存在哪里的?
答案是init函数,init函数是个尾递归函数,当接收到其它进程发送的消息时,如add,那么init(Count)会首先把Count+1返回给发送消息的进程,然后调用init(Count+1),等待下个消息。因此进程的状态在拥有receive...end块的函数的参数中。

阅读(3191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~