私は単純な銀行口座を運営するためのこのコードを持っています。 2つの入金方法と、口座への並行入金を初期化するためのテスト方法があります。Erlang - ファイル間の転送 - MUTEX
誰かが2つのアカウント間でお金を振り替える機能を実装するのに役立つでしょうか?デッドロックを防ぐためにmutexを追加しますか?
-module(bank).
-export([account/1, start/0, stop/0, deposit1/1, deposit2/1, get_bal/0, set_bal/1, withdraw/1]).
%test
-export ([test/3,user/3]).
account(Balance) ->
receive
{set, NewBalance} ->
account(NewBalance);
{get, From} ->
From ! {balance, Balance},
account(Balance);
{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);
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.
deposit1(Amount) ->
OldBalance = get_bal(),
NewBalance = OldBalance + Amount,
set_bal(NewBalance).
deposit2(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.
test(Nbuser, Nbdeposit, Method) ->
start(),
done = spawn_users(Nbuser,Nbdeposit,Method,self()),
receive_loop(Nbuser),
Res = (get_bal() == Nbdeposit*Nbuser),
stop(),
Res.
spawn_users(0,_Nbdeposit,_Method,_Pid) -> done;
spawn_users(Nbuser,Nbdeposit,Method,Pid) ->
spawn(?MODULE,user,[Nbdeposit,Method,Pid]),
spawn_users(Nbuser-1,Nbdeposit,Method,Pid).
receive_loop(0) -> done;
receive_loop(N) ->
receive
end_deposit -> receive_loop(N-1)
end.
user(0,_,Pid) ->
get_bal(), % to be sure that with method deposit1, the last set_bal is processed
Pid ! end_deposit;
user(N,Method,Pid) ->
?MODULE:Method(1),
user(N-1,Method,Pid).