Concurrency in Programming Languages


Published on

Presentation for 433-630 Principle of Programming Languges

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Concurrency in Programming Languages

  1. 1. Yudong Li May 2009
  2. 2.  A concurrent program needs to perform several possibly unrelated tasks at the same time.  The most common tool to deal with concurrency is thread.  Thread is an individual entity of execution from the main programs, and thread can give birth to another thread.  Concurrency when multiple threads created.  Multi-thread is not really simultaneous execution, but with time slot allocation with certain algorithm (e.g. Round Robin)
  3. 3.  Two ways  Extends java.lang.Thread class  Implement java.lang.Runnable interface  Steps  Create a thread  Implement run() function  Execute
  4. 4. class MyThreadA implements Runnable{ class MyThreadA extends Thread{ public void run(){ public void run(){ for(int i=0;i<5;i++){ for(int i=0;i<5;i++){ System.out.println(“Thread A is running”). System.out.println(“Thread A is running”). } } } } } } class MyThreadB extends Thread{ class MyThreadA implements Runnable{ public void run(){ public void run(){ for(int i=0;i<5;i++){ for(int i=0;i<5;i++){ System.out.println(“Thread A is running”). System.out.println(“Thread B is running”). } } } } } } class Test{ class Test{ public static void main(String[] args){ Thread t1 = new Thread(new MyThreadA()); Public static void main(String[] args){ Thread t2 = new Thread(new MyThreadB()); new MyThreadA().start(); t1.start(); t2.start(); new MyThreadB().start(); } } } }
  5. 5.  The result is not deterministic  Can add priority to control the order  static int MAX_PRIORITY  static int MIN_PRIORITY  static int NORM_PRIORITY
  6. 6.  Control.Concurrent module  data ThreadId  An abstract type representing a handle to a thread.  forkIO :: IO() -> IO ThreadId  Takes an IO action as its argument, and spawns it as a concurrent thread. Once created, run concurrently with other threads.
  7. 7. import Control.Concurrent (forkIO) import IO printThread :: IO() printThread = do { forkIO(hPutStr stdout “ThreadA”); forkIO(hPutStr stdout “ThreadB”); hPutStr stdout “ThreadC” }
  8. 8.  Haskell thread is light-weight  The print result differs from Java:  Java: ThreadA is running…ThreadB is running…  Haskell: TThThrhrereaeadadCdAB…
  9. 9.  Several threads modify same sharing resource  Use implicitly lock -- synchronized -- to make resource accessible to only one thread at a time. class Account { int balance; synchronized public void deposit(double amount){ balance = balance – amount; } public void withdraw(double amount){ depoist(-amount) } } void transfer(Account from, Account to, Double amount){ from.withDraw(amount); to.deposit(amount); }
  10. 10.  Intermediate State During the deposit and withdraw, other thread can observe a state that money in neither of the two accounts. Add lock: from.lock(); to.lock(); from.withdraw(amount); to.depoist(amount); from.unlock(); to.unlock();  Deadlock Account A Account B Thread A ---------------------> lock A, waiting for the lock B Thread B <--------------------- lock B, waiting for the lock A During the process of competing for the lock, each thread will hold one lock and wait indefinitely for another lock that will never come.
  11. 11.  A concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing. (wiki.)  Execute body without lock  Write all the calls and values into a log  After execution finishes, validate the log with real value, commit if success or retry if failed.
  12. 12. Running STM Operations TVar Operation atomically :: STM a -> IO a newTVar :: a -> STM (TVar a) retry :: STM a readTVar :: TVar a -> STM a orElse :: STM a -> STM a -> STM a writeTVar :: TVar a -> a -> STM()
  13. 13. limitedWithdraw :: Account -> Int -> STM() limitedWithdraw acc amount = atomically do { bal <- readTVar acc; check (amount <= 0 || amount <= bal); writeTVar acc (bal – amount) } check :: Bool -> STM() check True = return () check False = retry
  14. 14.  Logically occur at a single instant of time  Intermediate states are not visible to others  Modifying shared memory or resource without worrying about other threads.  No threads need to wait for access to resource.  Different threads can modify disjoint data in the same data structure.
  15. 15.  Retry: when different threads constantly update the same variable, there is no way to achieve concurrency and some transactions may rollback many times.  Commit overhead: particularly when programs do not perform much work inside transactions, the commit overhead appears to be very high.
  16. 16.  Transaction content: In order to make rollback available, there is a restriction on what functions can be done during a transaction. Especially for I/O functions, since its hard to undone those functions, it is not allowed to do so.  It might be possible to use buffers to temporarily store those operations and execute it after the thread commits. But too much cost.
  17. 17.  Haskell is one of the first languages that integrates STM in its mainstream distribution.  Also lots of implementations in other languages like C++, C#, Java. But none of them include STM in its distribution.  Some concept are easy to define in Haskell, but difficult in OO languages, like Retry or Monad.