ellang 中进程异步通信中的信箱与保序
erlang 进程通讯中 执行到 receive 语句时 如果信箱没有消息可以匹配时会暂停等待消息.
go() ->
register(echo, spawn(test_pid,loop,[])),
echo ! {self(), hello},
receive
{_Pid,Msg} ->
io:format("~w~n",[Msg])
end.
%%Pid ! stop. loop() ->
io:format(" loop start~n", []),
receive
{From, Msg} ->
io:format(" loop : ~w | ~w~n", [From, Msg]), From ! {self(), Msg},
loop();
stop -> io:format(" loop : ~w~n", [stop]), true
%% true
end.
由于信箱是先进先出,向同一个进程发送的消息,处理返回一定是保序的。 但这只限于一直不出错,匹配成功的情况,比如 revecie支持 timeOut, timeOut 后 进程将不在主动响应, 但是还能接收信息.
read(Db, Key) ->
Db ! {self(), {read, Key}},
receive
{read, R} -> {ok, R};
{error, Reason} -> {error, Reason}
after 10000 -> {error, timeout}
end. db() ->
receive
{Pid, {read, 2}} -> Pid ! {read, 2},db();
{Pid, {read, 3}} -> Pid ! {read, 3},db();
{Pid, {read, 5}} -> Pid ! {error, "not Reason"},db()
end.
假如 有以下调用(Db 是个查询进程,查询完毕会给当前进程返回查询结果)
read(Db, 1).
read(Db, 2).
//after 1500
read(Db, 6).
如果 read(Db, 1). 触发了timeout, 而且 read(Db, 2). 返回了{read, R}. 那么这时信箱处于阻塞状态,当read(Db,6).执行时, 会从信箱中取出第一条匹配返回. 所以 read(Db, 6).会返回 {ok, 2}.
如果是在终端直接运行测试,可以这样写
read(Db, Key) ->
Db ! {self(), {read, Key}},
receive
{read, R} -> {ok, R};
{error, Reason} -> {error, Reason}
after 10000 -> test(self()), {error, timeout}
end. db() ->
receive
{Pid, {read, 2}} -> Pid ! {read, 2},db();
{Pid, {read, 3}} -> Pid ! {read, 3},db();
{Pid, {read, 5}} -> Pid ! {error, "not Reason"},db()
end. test(Pid) ->
Pid ! {read, 2}.
在timeout 的时候往信箱里塞一条信息,然后你会看到

所以这时候,信箱的顺序就是错乱的, 那解决办法呢,一种是每次匹配前清理上一条消息,另一种则是加个唯一标识收到消息时匹配下是不是自己要的信息.

ellang 中进程异步通信中的信箱与保序的更多相关文章
- 有关map中使用iterate迭代器遍历的不保序问题和list remove(object)的细节问题
今天在做项目的过程中发现了如下两个问题: 一 使用map的iterator迭代器对map进行遍历得到的结果是不保序的,也就是每次输出结果都是不一样的.针对这个问题,看以下iterator迭代器的源码. ...
- Linux 系统中进程5中常见状态
运行.中断.不可终端.僵死.停止 R(运行):正在运行 or 在运行队列中等待: S(中断):处于休眠中,等待接收信号,并脱离改状态: D(不可中断):不响应信号输入,即使kill也不起作用: Z(僵 ...
- linux中进程控制
1.进程标识 每个进程都有一个非负整型表示的唯一的进程ID.进程ID标识符总是唯一的. 虽然进程ID是唯一的,但某个ID被回收后,ID号是可以复用的. ID为0的进程通常是调度进程(其常常被称交换进 ...
- 第11讲- Android中进程及其优先级
第11讲Android中进程及其优先级 进程与线程: 进程:操作系统结构的基础,资源分配的最小单元,一个操作系统包括多个进程: 线程:线程存在于进程当中,是操作系统调试执行的最小单元,一个进程包括多个 ...
- qt中进程的使用
qt中的进程使用需要用到头文件:include<QProcess> 首先来看看需要用到的主要的函数 (1)进程的定义: QProcess *mprocess; //定义一个进程参数 (2) ...
- Python中进程
程序 程序:编写完的代码称为程序. 进程 进程:又称重量级进程,正在执行中的程序称为进程.进程的执行会占用内存等资源.多个进程同时执行时,每个进程的执行都需要由操作系统按一定的算法(RR调度.优先数调 ...
- 对Linux0.11 中 进程0 和 进程1分析
1. 背景 进程的创建过程无疑是最重要的操作系统处理过程之一,很多书和教材上说的最多的还是一些原理的部分,忽略了很多细节.比如,子进程复制父进程所拥有的资源,或者子进程和父进程共享相同的物理页面,拥有 ...
- Python多进程库multiprocessing中进程池Pool类的使用
问题起因 最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似ba ...
- Python多进程库multiprocessing中进程池Pool类的使用[转]
from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...
随机推荐
- hdu 3549 Flow Problem (最大流)
裸最大流,做模板用 m条边,n个点,求最大流 #include <iostream> #include <cstdio> #include <cstring> #i ...
- 给新手的 10 个有用 Linux 命令行技巧
我记得我第一次使用 Linux 的时候,我还习惯于 Windows 的图形界面,我真的很讨厌 Linux 终端.那时候我觉得命令难以记忆,不能正确使用它们.随着时间推移,我意识到了 Linux 终端的 ...
- 教程-Delphi源代码--后延函数
说明: 1)TTtimer控件 TTtimer控件的实质是调用WindowsAPI定时函数SetTimer和KillTimer来实现的,并简化了对WM_TIMER消息的处理过程.通过设置OnTimer ...
- nyoj 540 奇怪的排序
奇怪的排序 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 最近,Dr. Kong 新设计一个机器人Bill.这台机器人很聪明,会做许多事情.惟独对自然数的理解与人类 ...
- 取正在运行的DLL或EXE的路径
function GetSelfPath: string;var ModuleName: string; i: Integer;begin SetLength(ModuleName, 255); ...
- 正则表达式_matches(Regex)
[0-9a-zA-Z.%+-] 匹配中括号中的 0-9 或者 a-z 或者 A-Z 或者 . 或者 % 或者 + 或者 - $p = "111,222,333"$p -match ...
- cocos2d-x游戏开发实战原创视频讲座系列1之2048游戏开发
cocos2d-x游戏开发实战原创视频讲座系列1之2048游戏开发 的产生 视持续更新中.... 视频存放地址例如以下:http://ipd.pps.tv/user/1058663622 ...
- IFrame 根据嵌入页面自动调节大小
很多人估计会遇到这样的情况,在IFrame嵌入某些页面,总会出现滚动条,那么有没方法,可以让IFrame随着嵌入页面的内容大小自动调节大小而不出现滚动条呢?答案是肯定的,经过查找,本人发现用Ifram ...
- Java编程思想第四版*第七章*个人练习
欢迎加群:239063848 成团的笔记:该组仅用于技术共享和交流,问题和答案公布 潘基聊天.禁止广告.禁止招聘-- 练习1:(2)创建一个简单的类.第二个类中,将一个引用定义为第一个类的对象.运用惰 ...
- <ASP.NET4 从入门到精通>学习笔记3
第三部分,状态管理与缓存 何为状态管理.起始对于web而言.经过前面章节的解说.已经理解,对于web程序,就是一个无状态的程序.每次的请求与每次的响应,两者之间本身就是独立存在的,这一点对于早期的静态 ...