以下代码片段由Francesco Cesarini和Erlang编程的Simon Thompson撰写,作为Erlang中可能的竞争条件的一个例子.
start() ->
case whereis(db_server) of
undefined ->
Pid = spawn(db_server, init, []),
register(db_server, Pid),
{ok, Pid};
Pid when is_pid(Pid) ->
{error, already_started}
end.
Run Code Online (Sandbox Code Playgroud)
在没有逐字复制细节的情况下,作者解释说如果两个进程同时执行start(),那么运行"undefined"部分的进程1可能无法完成,因为进程2会导致它被抢占.然后,进程2将运行"未定义"部分以完成.现在,当进程1恢复时,进程2已经注册了db_server,导致其对register()的调用抛出运行时错误.我希望你能理解我的意思,因为我不想翻阅这本书的文字.
我的问题是,当两个进程同时执行start()时,如何编码上述确切的功能以避免潜在的竞争条件?
通常,这可以通过让生成的进程注册自己的名称,然后向父进程发回一个响应来告诉父进程是否成功.
start() ->
Pid = spawn(db_server, init, [self()]),
receive {Pid, StartResult} ->
StartResult
end.
init(Parent) ->
try register(db_server, self()) of
true ->
Parent ! {ok, started},
real_init()
catch error:_ ->
Parent ! {error, already_started}
end.
Run Code Online (Sandbox Code Playgroud)
(可能无法编译或工作.输入此处而不检查.:))
你可以在gen.erl中找到一个精心实现的版本.实际上,在实际代码中,您只需使用OTP行为来重用该版本.
| 归档时间: |
|
| 查看次数: |
1243 次 |
| 最近记录: |