分布式、并行计算语言Erlang 学习笔记(第二部分)
Concurrent Programming 并发编程
- Definitions 定义
- Creating a new process 创建新进程
- Simple message passing 简单消息传递
- An Echo Process 一个Echo进程
- Selective Message Reception 选择性的消息接受
- Selection of Any Message 任意消息的选择
- A Telephony Example 电话的例子
- Pids can be sent in messages 带有Pid的消息
- Registered Processes 注册进程
- The Client Server Model 客户端/服务器端模型
- Timeouts 超时
Definitions 定义
- Process - A concurrent activity. A complete virtual machine. The system may have many concurrent processes executing at the same time.
进程——一个并发活动。一个完整的虚拟机。这个系统可以同时拥有很多个并发进程。 - Message - A method of communication between processes.
消息——一种进程间通讯的方式。 - Timeout - Mechanism for waiting for a given time period.
超时——对一个有限长度的时间间隔的等待机制。 - Registered Process - Process which has been registered under a name.
注册进程——有名字的进程。 - Client/Server Model - Standard model used in building concurrent systems.
C/S模式——构建并发系统的标准模式。
Creating a New Process 创建一个新进程
Before之前Code in Pid1 (Pid1中的代码)
Pid2 = spawn(Mod, Func, Args)
After之后
Pid2 is process identifier of the new process - this is known only to process Pid1.
Pid2被标识为新进程,只被进程Pid1所知晓。
Simple Message Passing 简单消息传递
self() - returns the Process Identity (Pid) of the process executing this function.
self()——返回当前正在执行的函数所在的进程的Pid标识符。
From and Msg become bound when the message is received. Messages can carry data.
From和Msg 构成消息传递的边界。消息可以携带数据。
- Messages can carry data and be selectively unpacked.
消息可以携带数据,并可以被有选择性的解包(unpack)。 - The variables A and D become bound when receiving the message.
变量A和D构成消息传递的边界(即被绑定在一起)。 - If A is bound before receiving a message then only data from this process is accepted.
如果B在接收到消息之前是绑定到A,那么只有来自于A的消息(数据)才会被接受。
An Echo process 一个Echo进程
-module(echo). -export([go/0, loop/0]). go() -> Pid2 = spawn(echo, loop, []), Pid2 ! {self(), hello}, receive {Pid2, Msg} -> io:format("P1 ~w~n",[Msg]) end, Pid2 ! stop. loop() -> receive {From, Msg} -> From ! {self(), Msg}, loop(); stop -> true end.
Selective Message Reception 有选择的消息接受
The message foo is received - then the message bar - irrespective of the order in which they were sent.
消息foo被接受——然后才是消息bar被接受,这和它们被发送的顺序无关。
Selection of any message 任意消息的选择
The first message to arrive at the process C will be processed - the variable Msg in the process C will be bound to one of the atoms foo or bar depending on which arrives first.
第一条消息抵达进程C被处理,进程C中的变量Msg将被绑定为字符串boo或者bar,这取决于虽首先到达。
A Telephony Example 电话的例子
This is the code in the process `Call. A and B are local bound variables in the process Call.![]()
ringing_a(A, B) -> receive {A, on_hook} -> A ! {stop_tone, ring}, B ! terminate, idle(A); {B, answered} -> A ! {stop_tone, ring}, switch ! {connect, A, B}, conversation_a(A, B) end.
上面的代码是进程Call的。A和B都是进程C的本地绑定变量。
Pids can be sent in messages 带有Pid的消息
- A sends a message to B containing the Pid of A.
A发送消息给B,包含着A的Pid。 - B sends a transfer message to C.
B将消息转交给C。 - C replies directly to A.
C直接向A回应。
Registered Processes 注册进程
register(Alias, Pid) Registers the process Pid with the name Alias.
register(Alias, Pid)将给定的Pid附上名字Alias。
start() -> Pid = spawn(num_anal, server, []) register(analyser, Pid). analyse(Seq) -> analyser ! {self(),{analyse,Seq}}, receive {analysis_result,R} -> R end.Any process can send a message to a registered process.
任意的进程都可以发送消息给注册进程。
Client Server Model C/S模型
Protocol 协议
Server code 服务器代码
-module(myserver). server(Data) -> receive {From,{request,X}} -> {R, Data1} = fn(X, Data), From ! {myserver,{reply, R}}, server(Data1) end.
Interface Library 接口库
-export([request/1]). request(Req) -> myserver ! {self(),{request,Req}}, receive {myserver,{reply,Rep}} -> Rep end.
Timeouts 超时
If the message foo is received from A within the time Time perform Actions1 otherwise perform Actions2.
如果从A出来的消息foo在Time时间内被接受,执行Actions1,否则执行Actions2。
Uses of Timeouts 使用超时
sleep(T)- process suspends for T ms.sleep(T)-进程挂起T毫秒。
sleep(T) -> receive after T -> true end.suspend() - process suspends indefinitely.
suspend() -进程被挂起不确定的时间。
suspend() -> receive after infinity -> true end.alarm(T, What) - The message What is sent to the current process iin T miliseconds from now 。
alarm(T, What) -消息What从现在起经过T毫秒之后被发出。
set_alarm(T, What) -> spawn(timer, set, [self(),T,What]). set(Pid, T, Alarm) -> receive after T -> Pid ! Alarm end. receive Msg -> ... ; endflush() - flushes the message buffer
flush() -清空消息缓冲区。
flush() -> receive Any -> flush() after 0 -> true end.
A value of 0 in the timeout means check the message buffer first and if it is empty execute the following code.
一个超时为0的代码意味着首先检查消息缓冲区,如果为空,则执行下面的代码。