Chinaunix首页 | 论坛 | 博客
  • 博客访问: 741712
  • 博文数量: 130
  • 博客积分: 2951
  • 博客等级: 少校
  • 技术积分: 1875
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-04 18:32
文章分类

全部博文(130)

文章存档

2013年(1)

2012年(129)

分类: Python/Ruby

2012-03-13 18:00:21

    Erlang里,如果某个消息迟迟不来, 那么receive有可能进入无限的等待中(比如发送消息的进程crash了)。为了避免这种情况, 可以在receive语句中加入一个超时处理,语法是:

  1. receive
  2.     Pattern1 [when Guard1] ->
  3.         Expressions1;
  4.     Pattern2 [when Guard2] ->
  5.         Expressions2;
  6.     ...
  7. after Time ->
  8.     Expressions
  9. end
    在进入receive等待后,如果在Time规定的时间内没有收到消息,则进程停止等待,进入Expressions进行求值。
利用超时实现一个计时器
  1. -module(stimer).
  2. -export([start/2, cancel/1]).
  3. start(Time, Fun) -> spawn(fun() -> timer(Time, Fun) end).
  4. cancel(Pid) -> Pid ! cancel.
  5. timer(Time, Fun) ->
  6.     receive
  7.         cancel ->
  8.             void
  9.     after Time ->
  10.         Fun(),
  11.         timer(Time, Fun)
  12.     end.
flush_buffer()清空当前进程的邮箱:
  1. flush_buffer() ->
  2.     receive
  3.         AnyMessage ->
  4.             flush_buffer()
  5.         after 0 ->
  6.             true
  7.     end.
只要邮箱中还有消息,第一个消息会被匹配到(未绑定变量AnyMessage会匹配到任何消息,在这里就是第一
个消息),然后flush_buffer会再次被调用,但是如果邮箱已经为空了,那么函数会从超时子句中返回。

消息的优先级也可以通过使用0作为超时长度来实现:
  1. priority_receive() ->
  2.     receive
  3.         interrupt ->
  4.             interrupt
  5.     after 0 ->
  6.         receive
  7.             AnyMessage ->
  8.                 AnyMessage
  9.         end
  10.     en
函数priority_receive会返回邮箱中第一个消息,除非有消息interrupt发送到了邮箱中,此时将返
回interrupt。通过首先使用超时时长0来调用receive去匹配interrupt,我们可以检查邮箱中是否已经有了
这个消息。如果是,我们就返回它,否则,我们再通过模式AnyMessage去调用receive,这将选中邮箱中的
第一条消息。

超时报警程序:
  1. -module(mytimer).
  2. -export([start/0, timeout/2, cancel/1, timer/3]).

  3. start() ->
  4.     %io:format("~w", [self()]),
  5.     timeout(1000,warning),
  6.        receive
  7.         Alarm->
  8.             io:format("~w~n", [Alarm])
  9.     end.

  10. timeout(Time, Alarm) ->
  11.     spawn(mytimer, timer, [self(), Time, Alarm]).

  12. cancel(Timer) ->
  13.     Timer ! {self(), cancel}.

  14. timer(Pid, Time, Alarm) ->
  15.     io:format("~w~n", [Pid]),
  16.     receive
  17.         {Pid, cancel} ->
  18.             true
  19.     after Time ->
  20.         io:format("~w", [Pid]),
  21.         Pid ! Alarm
  22.     end.
阅读(2091) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~