Erlang并发与并发编程(二)
上节我主要讲了Erlang并发编程的模型和相关概念,详见:Erlang并发与并发编程(一),本节将主要讲述我对于Erlang并发编程的理解,本文主要思想来源于书籍:《Erlang程序设计》。
我们知道操作系统有自己的一套原语,Erlang也有自己的原语系统。首先,我们要明白的就是Erlang中的进程与OS中的进程是不一样的,它们是不等同的,在Erlang编程的时候,可以创建、链接Erlang自己的进程,它们运行在Erlang虚拟机(VM)上,如下示意图清晰地道明了OS进程与Erlang进程的区别:
Erlang三个并发原语:
- spawn原语:
Pid = spawn(Fun) %% 创建一个新的进程,用于对Fun求值,返回值为Pi,
在分布式系统编程中时,spawn还有一个参数,可以指定在某个节点(Node)上创建一个进程,其中的Fun,是一个函数引用,意思是创建一个进程用于对Fun函数进行求值或运算; - send原语:
Pid ! message %% 向进程发送消息,返回值为消息本身
注:Erlang中的发送消息原语不是send,而是感叹号“!”;当然可以向多个进程发送同一条消息,如:Pid 1!Pid2!… !Message %%将消息发送到多个进程
-
receive原语:格式为:Receive … and %%接受一个发给当前进程的消息,语法如下:
Receive
Pattern1 [when Guard1] ->
Expression1;
Pattern2 [when Guard2] ->
Expression2;
… %% 后面还会讲到,receive原语,还涉及到超时的问题
end.
小例:功能:求圆或矩形的面积。
-module(area_server0).
-export([loop/0]).
loop() ->
receive
{rectangle,Width,Ht} ->
io:format("Area of rectangle is ~p~n",[Width * Ht]),
loop();
{circle,R} ->
io:format("Area of circle is ~p~n",[3.14159 * R *R]),
loop();
Other ->
io:format("I don't know what the area of a ~p~n",[Other]),
loop()
end.
在Erlang命令窗口中运行一下:
客户/服务器:
客户/服务器架构是Erlang的核心内容,在Erlang中,客户/服务器架构下的客户机和服务器都是分离的进程,它们之间的通信都需要Erlang的消息传递机制。客户机和服务器可以运行在同一台机器上,也可以运行在不同的机器上。
小例:第一个客户服务器,功能:求圆或矩形的面积。(源码不再机器上,截图给大家,请初学者自己敲敲代码熟悉)
在Erlang命令窗口中运行一下:
一点瑕疵:
在area_server1:rpc/2中,我们向服务器发送一个请求,然后等待回应。 如果在这个客户机等待来自服务器的回应时,其他的进程也向这个客户机发送了消息,那么它会把这个消息误认为是来自服务器的回应。
例如,发送信息时,客户机将自己的地址发给了服务器;接受信息时,服务器并没有将他的地址告知客户机。
因此,下节我会继续并发编程问题进行阐述,将上述这个问题解决,同时引进接受信息超时的问题。