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类的使用 ...
随机推荐
- openstack 镜像自动扩容 resize拉伸
The simplest way to support this in your image is to install the cloud-utils package (contains the g ...
- 问题-RZ安装后报错“RzBorder.pas”
错误象现:[Error] RzBorder.pas(1429): Number of elements differs from declaration [Fatal Error] RzEdit.pa ...
- 143. Sort Colors II
最后更新 一刷 class Solution { public void sortColors2(int[] colors, int k) { // write your code here if ( ...
- vue相关
勾三股四的vue+webpack实战:http://jiongks.name/blog/just... 用Vue构建一个Notes App:https://coligo.io/learn-vuex-. ...
- new Date() iso不支持兼容性问题
在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象. 但是在IOS5版本里面的Safari解释ne ...
- spring的有状态BEAN和无状态BEAN
有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”:一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束.即每个用户最初都会得到一 ...
- WebSerivce测试工具 Storm
STORM 是一款免费且开源的WebSerivce测试工具 它的功能: 1,测试任意语言测试 WebService 2,可动态调用webservice的方法,即使输入参数需要使用复杂的数据类型 3,节 ...
- [转]非常好的vsftpd安装于配置
环境:CentOS 5.0 操作系统一.安装:1.安装Vsftpd服务相关部件:[root@KcentOS5 ~]# yum install vsftpd*Dependencies Resolved= ...
- Delphi 第三方组件
TMS Component Pack v7.0.0.0 TMS Component Pack 版本为Delphi和C++ Builder提供了超过350个VCL组件,用以创建功能丰富的.现代的和原生W ...
- Cocos2D-x培训课程
1.1 Cocos2D-x 什么是cocos2d-x cocos2d-x在游戏开发中的运用 cocos2d-x的几个重要版本特点 iOS环境下搭建cocos2d开发环境 windows平台搭建coco ...