【发布时间】:2015-02-17 08:52:49
【问题描述】:
我目前有一个使用 erlang 编写的简单银行账户,我也重写了同一个银行账户,以期相互排斥,其想法是不能进行两次存款,其中设置/获取余额可以中断,以便最终值错误,例如 bal A = 10 bal B = 20:
WRONG
get_bal.A 0 → get_bal.B 0 → set_bal.A 10 → set_bal.B 20 == 20
RIGHT
get_bal.A 0 → set_bal.A 10 → get_bal.B 10 → set_bal.B 30 == 30
我的代码初始代码如下:
-module(bank).
-export([account/1, start/0, stop/0, deposit/1, get_bal/0, set_bal/1]).
account(Balance) ->
receive
{set, NewBalance} ->
account(NewBalance);
{get, From} ->
From ! {balance, Balance},
account(Balance);
stop -> ok
end.
start() ->
Account_PID = spawn(bank, account, [0]),
register(account_process, Account_PID).
stop() ->
account_process ! stop,
unregister(account_process).
set_bal(B) ->
account_process ! {set, B}.
get_bal() ->
account_process ! {get, self()},
receive
{balance, B} -> B
end.
deposit(Amount) ->
OldBalance = get_bal(),
NewBalance = OldBalance + Amount,
set_bal(NewBalance).
这个想法是设置一个测试,这样如果最终余额可能错误,我可以收到错误消息,如果按计划进行,我可以通过。 我重写的代码也如下:
account(Balance) ->
receive
{deposit, Amount, From} ->
NewBalance = Balance + Amount,
From ! {deposit, Amount, NewBalance},
account(NewBalance);
{withdraw, Amount, From} when Amount > Balance ->
From ! {error, {insufficient_funds, Amount, Balance}},
account(Balance);
{withdraw, Amount, From} ->
NewBalance = Balance - Amount,
From ! {withdrawal, Amount, NewBalance},
account(NewBalance);
{get, From} ->
From ! {balance, Balance},
account(Balance);
stop -> ok
end.
deposit(Amount) when Amount > 0 ->
account_process ! {deposit, Amount, self()},
receive
{deposit, Amount, NewBalance} ->
{ok, NewBalance}
end.
withdraw(Amount) when Amount > 0 ->
account_process ! {withdraw, Amount, self()},
receive
{withdrawal, Amount, NewBalance} ->
{ok, NewBalance};
Error ->
Error
end.
感谢您的阅读,我们将不胜感激。
【问题讨论】:
-
我用代码示例更新了我的答案。我将您的银行功能重新实现为 Erlang gen_server。这是一种更“Erlangy”构建银行功能的方式。
标签: erlang mutex mutual-exclusion