施加互斥成一个Erlang示例(Applying a mutex into an erlang ex

2019-10-21 22:17发布

我当前使用的Erlang编写了一个简单的银行帐户,我想一个互斥体加入到它,这样两个存款不能进行,其中设置/获取平衡可以所中断,这样的终值是错误的,例如BAL A = 10平衡 - = 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).

我想知道,如果有人能够实现与简短的注释互斥来解释你的思维过程。 将是一个巨大的帮助! 再次感谢

Answer 1:

账户过程的消息队列可以提供,如果你正确地使用它,你追求的效果。 例如,您的deposit/1功能有问题,因为它执行读-修改-写,这里的读取和写入是两个单独的操作。 因为他们是独立的,他们让其他无关的动作在它们之间潜入和打破你正在执行外帐算算。

为什么不反而让账户做自己的数学? 毕竟,账户持有资金,所以它没有意义做外帐的算了一笔账。

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/1只是增加了原子的资金,并返回新的平衡:

deposit(Amount) when Amount > 0 ->
    account_process ! {deposit, Amount, self()},
    receive
        {deposit, Amount, NewBalance} ->
            {ok, NewBalance}
    end.

同样, withdraw/1只减去基金原子如果可能的话,返回新的平衡,或者会发生透支返回一个错误:

withdraw(Amount) when Amount > 0 ->
    account_process ! {withdraw, Amount, self()},
    receive
        {withdrawal, Amount, NewBalance} ->
            {ok, NewBalance};
        Error ->
            Error
    end.

所述get_bal/0功能保持相同。

通过这种方法,所有的交易都是原子。



文章来源: Applying a mutex into an erlang example
标签: erlang mutex