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 电话的例子
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.
This is the code in the process
`Call.
A and
B are local bound variables in the process
Call.
上面的代码是进程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 ->
... ;
end
flush() - 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的代码意味着首先检查消息缓冲区,如果为空,则执行下面的代码。