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类的使用 ...
随机推荐
- LightOj 1282 Leading and Trailing
求n^k的前三位数字和后三位数字. 范围: n (2 ≤ n < 231) and k (1 ≤ k ≤ 107). 前三位: 设 n^k = x ---> lg(n^k)=lg(x) - ...
- python module的结构
python有很多module,下面是module的结构图: 拿httplib做例子,httlip module有: 4个class( HTTPConnection,HTTPSConnection,H ...
- tar命令的详解
tar命令 [root@linux ~]# tar [-cxtzjvfpPN] 文件与文件夹 ....參数:-c :建立一个压缩文件的參数指令(create 的意思):-x :解开一个压缩文件的參数指 ...
- Linux多线程的一个小例子
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h& ...
- iOS开发多线程篇---atomic nonatomic区别
摘要 atomic和nonatomic区别用来决定编译器生成的getter和setter是否为原子操 作.atomic提供多线程安全,是描述该变量是否支持多线程的同步访问,如果选择了atomic 那么 ...
- Xcode快捷键、小技巧与xib圆角设置
快捷键: 1.StoryBoard技巧 当你想直接在view中选择自己想要的元素时,但是又碍于一个view上叠加的元素太多很难直接选中,那么在这时,你同时按住键盘上的shift和 control键,然 ...
- 怎么在AptanaStudio中把电脑中的浏览器设置为默认执行方法
1.在Aptana中找到按钮 2.点击向下的三角形找到
- Winedt10 添加自定义宏
Winedt10 添加自定义功能,并在toolbar上添加快捷命令 功能描述: 用宏实现latex+bib参考文献的一键编译. Remark: The toolbar is the most visi ...
- Linux基础命令(三)
一.常用命令—文件目录类命令 1.ls 列出指定或默认目录的文件信息 使用形式: ls [选项] [目录名] 实例: $ls $ls –als $ls /home/sq/Desktop $ls ./D ...
- JQuery对象与DOM对象分析
一.定义: DOM对象(文档对象模型):暂时这么理解:通过JavaScript获取的HTML元素,称为DOM对象.如:var domID=document.getElementById("i ...