软件事务内存 - 可组合性示例 [英] Software Transactional Memory - Composability Example
问题描述
我正在寻找一个简单的例子,用实际代码来说明这一点。我喜欢在Clojure中的一个例子,但Haskell也很好。
一个例子,当锁被禁止时用Java编写:
class Account {
float balance;
synchronized void deposit(float amt){
balance + = amt;
}
同步void withdraw(float amt){
if(balance< amt)
throw new OutOfMoneyError();
balance - = amt;
}
synchronized void transfer(Account other,float amt){
other.withdraw(amt);
this.deposit(amt);
}
}
因此,存款是好的,转移不正常:如果A开始转移到B,当B开始转移到A,我们可能有一个死锁情况。
现在在Haskell STM:
withdraw :: TVar Int - > Int - > STM()
撤销acc n = do bal< - readTVar acc
如果bal<然后重试
writeTVar acc(bal-n)
deposit :: TVar Int - > Int - > STM()
deposit acc n = do bal< - readTVar acc
writeTVar acc(bal + n)
deposit :: TVar Int-> TVar Int - > Int - > STM()
从到n的转移从n
存款转到n
由于没有明确的锁, withdraw
和 deposit
code>。语义仍然确保如果提取失败,则整个传输失败。它还确保退出和存款将原子性地完成,因为类型系统确保您不能在原子
之外调用转移。
atomically :: STM a - > IO a
此示例来自于:
http://cseweb.ucsd.edu/classes/wi11/cse230/static/lec-stm-2x2.pdf
改编自本文,你可能想读:
http:// research。 microsoft.com/pubs/74063/beautiful.pdf
One of the major advantages of software transactional memory that always gets mentioned is composability and modularity. Different fragments can be combined to produce larger components. In lock-based programs, this is often not the case.
I am looking for a simple example illustrating this with actual code. I'd prefer an example in Clojure, but Haskell is fine too. Bonus points if the example also exhibits some lock-based code which can't be composed easily.
An example where locks don't compose in Java:
class Account{
float balance;
synchronized void deposit(float amt){
balance += amt;
}
synchronized void withdraw(float amt){
if(balance < amt)
throw new OutOfMoneyError();
balance -= amt;
}
synchronized void transfer(Account other, float amt){
other.withdraw(amt);
this.deposit(amt);
}
}
So, deposit is okay, withdraw is okay, but transfer is not okay: if A begins a transfer to B when B begins a transfer to A, we can have a deadlock situation.
Now in Haskell STM:
withdraw :: TVar Int -> Int -> STM ()
withdraw acc n = do bal <- readTVar acc
if bal < n then retry
writeTVar acc (bal-n)
deposit :: TVar Int -> Int -> STM ()
deposit acc n = do bal <- readTVar acc
writeTVar acc (bal+n)
deposit :: TVar Int -> TVar Int -> Int -> STM ()
transfer from to n = do withdraw from n
deposit to n
Since there is no explicit lock, withdraw
and deposit
compose naturally in transfer
. The semantics still ensure that if withdraw fails, the whole transfer fails. It also ensures that the withdraw and the deposit will be done atomically, since the type system ensures that you cannot call transfer outside of an atomically
.
atomically :: STM a -> IO a
This example comes from this: http://cseweb.ucsd.edu/classes/wi11/cse230/static/lec-stm-2x2.pdf Adapted from this paper you might want to read: http://research.microsoft.com/pubs/74063/beautiful.pdf
这篇关于软件事务内存 - 可组合性示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!