erlang的并发(二)

生产中erlang的并发处理大多都是依靠四大行为来完成,这个以后再说!

我们有的时候可能会误解一个问题就是一个接收消息是如何处理的,直观的去看,是A发一条消息给B,B处理以后返回一个消息,一开始我也这么想,但是这就又带来了另一个问题,那现在如果又有其他人也给B发消息怎么办,那我们就需要一个地方去存储些同时发来的消息,以供A来处理。

 

回想一下上回我们说的邮局问题

 

我们来扩展一下,人们将信件发送给邮局,邮局又将无数的信件发送给了每个人,但是收到信件的人无法处理如此多的信件,怎么办呢,那就用一个邮箱来代替,收信人打开邮箱去挑选(想想你拿着一沓信件是怎么看的呢,看过以后的信件放在最后然后看下一个,一次循环),没错,这是队列式的方式(关于进程邮箱很多资料都有详细介绍就不说了

 

我们在处理进程的问题时经常会出现并没有得到自己想要的消息,这怎么办?一直占用内存等待下去?

当然不会,简单的 receive处理为我们提供了一个小方法,就是after

把上次的程序扩展一下

 

rpc(Pid, Request) ->
	Pid ! {self(), Request},
	receive
		{Pid, Response} ->    %%用于确认是否是该进程发送的消息
			Response
	after 
		2000 ->
			past
	end.

loop() ->
	receive
		{From, {move, Distance}} ->
			From ! Distance,
			loop();
		{From, {jump, Distance}} ->
			From ! Distance,
			loop();
		{From, {stop, Time}} ->
			From ! Time,
			loop();
		{From, Other} ->
			From ! {error, Other},
			loop()
	after 
		2000 ->
			past
	end.

 数字2000是毫秒单位,你可以自己换算一下,根据自己的需要来调整。

 

 注册进程中我遇到了很多的问题,这样的时候一般会看节点信息和打印结果来分析

言归正传

我们来注册一个进程,(这里我还是稍有疑问,看一下测试)

 

-module(server3).
-export([
	test1/0,
	test2/0,
	test3/0
]).

test1() ->
	Pid1 = spawn(fun server1:loop/0),
	register(aaa, Pid1).

test2() ->
	Pid2 = spawn(fun server2:loop/0),
	register(bbb, Pid2).

test3() ->
	aaa ! 1000.

 

 我调用了test1()和test3(),结果出乎意料,是bad argument。就是说我注册的进程名不对

E:\test>erl
Eshell V5.9  (abort with ^G)
1> server3:test1().
true
2> server3:test3().
** exception error: bad argument
     in function  server3:test3/0 (server3.erl, line 17)
 为什么?我又修改了一下代码

 

 

-module(server3).
-export([
	test1/0,
	test2/0
]).

test1() ->
	Pid1 = spawn(fun server1:loop/0),
	register(aaa, Pid1),
	aaa!1000.

test2() ->
	Pid2 = spawn(fun server2:loop/0),
	register(bbb, Pid2).
 测试一下
E:\test>erl
Eshell V5.9  (abort with ^G)
1> server3:test1().
1000
这里正确了。

但是我查看注册名的时候并没有我注册的aaa?
2> registered().
[code_server,global_name_server,file_server_2,
 application_controller,init,standard_error_sup,
 standard_error,global_group,erl_prim_loader,user,
 error_logger,rex,inet_db,kernel_sup,kernel_safe_sup]

这里查看aaa的进程id的时候也没有?
3> whereis(aaa).
undefined

但是我在注册进程中输入了这样一个消息
ฐErlang R15B (erts-5.9) [smp:4:4] [async-threads:0]

Eshell V5.9  (abort with ^G)
1> register(aaa, Pid).
* 1: variable 'Pid' is unbound
2> register(aaa, self()).
true
3> registered().         
[code_server,global_name_server,file_server_2,
 application_controller,init,user_drv,standard_error_sup,
 standard_error,global_group,erl_prim_loader,aaa,user,
 error_logger,rex,inet_db,kernel_sup,kernel_safe_sup]
4> 
4> whereis(aaa).
<0.31.0>
5> 
这次我们查到了我们注册的进程也查到了,它确实存在

 这时我不禁就开始猜想erlang的注册进程的实现范围,如果是在本进程对自己注册一个别名,那他注册到了哪里?self()注册时注册到了kernel这个app上,但是自己生成的一个新进程既我没有挂在同一个app上的时候的确报错了,为什么?一个节点下可以设置许多app来管理自己的代码,那么我们把范围缩小到app,那相同app下我们去创建两个进程来测试一下注册问题会是什么结果,下次就写一个完整的代码结构了测试一下!

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值