对于erlang,我并没用深入的研究过,充其量是一个业余选手,工作中用到了或有不懂得我就自己做做实验或看看源码给自己一个交代!
erlang的并发
erlang的并发在于进程,进程也是erlang的灵魂(至少我这么认为),并发也就是并行,你在运行我也在运行(我们不考虑计算机自身内存的处理方式,因为我们感觉不到),而且各自拥有自己的内存,A进程想于B进程互相交流就只能靠发送消息,然后依靠返回的结果让A进程知道B进程的一个状态
基本格式为(大家都知道)
Pid ! Message
receive
……
end
接下来让我们做一点有趣的事情
我们先来写一个接收的方法,然后我们来为这个文件写一个启动进程的方法
-module(server1).
-export([
loop/0,
create_process/0
]).
loop() ->
receive
{move, Distance} ->
io:format("How far we pasted:~p~n",[Distance])
loop();
{jump, Distance} ->
io:format("How far we jumpped:~p~n",[Distance*2])
loop();
{stop, Time} ->
io:format("How long has been pasted:~p~n",[Time]),
loop()
end.
%%方法返回的是Pid
create_process() ->
spawn(fun server1:loop/0).
我们来发条消息测试一下
E:\test>erl
Eshell V5.9 (abort with ^G)
1> Pid = server1:create_process().
<0.32.0>
2> Pid ! {move, 100}.
How far we pasted:100
{move,100}
上面的测试有了正确的返回结果(如果仔细观察你会产生这样一个问题,到底是谁给我们创建的这个进程发了这条消息呢?程序中并没有创建另一个进程啊!!!)
敲击self().命令我们控制台出现了一个进程号,原来控制台就是一个进程本身,也就是我们利用控制台进行消息发送给我们自己写的进程,如果你喜欢乱点乱看那么输入tv:start().会出现这样一个GUI界面点开Owner Name列里的一个app选项你就会看到消息是怎样一点点来回发送的了。
言归正传
刚才的程序很简单,没有任何交互在其中,我们来扩展成有交互并且能处理错误信息的一种程序
-module(server1).
-export([
loop/0,
rpc/2,
create_process/0
]).
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
Response ->
Response
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()
end.
create_process() ->
spawn(fun server1:loop/0).
这个程序运行结果可想而知,在控制台进程中会显示出请求的结果,
你可以自己试着为上面的程序加一个方法将rpc封装于其中,
这样的话我们的程序就多出一个对外的接口方法,
正常我们工作都是按照这个简单的框架去编写这样的一个程序,即便是其他的编程语言,也不会提倡直接调用文件内的内部方法,这只是一个很简单的例子,但对于他的扩展却意义很大,我们将逻辑方法写在其他的文件内,而上面的文件我们可以简单的把他当做一个消息集散中心来处理,那么就像邮局一样,每个城市都有自己的邮局,而信件就作为消息,每个人发送信件到邮局,我们再由邮局发送到每个人手中,你可以简单的想一下这样的过程