【发布时间】:2017-03-15 01:15:45
【问题描述】:
试图弄清楚 Erlang 并发是如何工作的。对于测试,我有以下模块:
server.erl:
-module(server).
-export([loop/0]).
loop() ->
receive
{foo, Msg_foo} ->
io:format("~w~n", [Msg_foo]),
loop();
{bar, Msg_bar} ->
io:format("~w~n", [Msg_bar]),
loop();
stop ->
io:format("~s~n", ["End server process"]),
true
end.
process_a.erl
-module(process_a).
-export([go_a/0]).
go_a() ->
receive
{foo, Pid1} ->
Pid1 ! {foo, 'Message foo from process A'},
go_a();
{bar, Pid2} ->
Pid2 ! {bar, 'Message bar from process A'},
go_a()
end.
process_b.erl
-module(process_b).
-export([go_b/0]).
go_b() ->
receive
{foo, Pid1} ->
Pid1 ! {foo, 'Message foo from process B'},
go_b();
{bar, Pid2} ->
Pid2 ! {bar, 'Message bar from process B'},
go_b()
end.
client.erl
-module(client).
-export([start/0]).
-import(server, [loop/0]).
-import(process_a, [go_a/0]).
-import(process_b, [go_b/0]).
go() ->
Server_Pid = spawn(server, loop, []),
Pid_A = spawn(process_a, go_a, []),
Pid_B = spawn(process_b, go_b, []),
Pid_A ! {foo, Server_Pid},
Pid_B ! {bar, Server_Pid},
Pid_A ! {bar, Server_Pid},
Pid_B ! {foo, Server_Pid},
Pid_A ! {foo, Server_Pid},
Pid_B ! {foo, Server_Pid},
Pid_A ! {bar, Server_Pid},
Pid_B ! {bar, Server_Pid}.
start() ->
go().
客户端向进程 A 和进程 B 发送消息,进程 B 依次向服务器发送消息。消息的顺序是:
A foo
B bar
A bar
B foo
A foo
B foo
A bar
B bar
但程序输出是:
'Message foo from process A'
'Message bar from process A'
'Message foo from process A'
'Message bar from process A'
'Message bar from process B'
'Message foo from process B'
'Message foo from process B'
'Message bar from process B'
服务器首先处理来自进程A的所有消息,然后处理来自进程B的所有消息。我的问题是,什么决定了消息处理顺序?我以为是收到消息的顺序。
【问题讨论】:
标签: concurrency process erlang