1 / 26

COMP 111

COMP 111. Threads and concurrency Sept 28, 2005. Who is this guy?. I am not Prof. Couch Obvious? Sam Guyer New assistant professor in CS Complete Ph.D. in 2003 at University of Texas Grew up in Boston Research area: Compilers Mostly, new applications and algorithms. My research.

gathers
Download Presentation

COMP 111

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. COMP 111 Threads and concurrency Sept 28, 2005

  2. Who is this guy? • I am not Prof. Couch Obvious? • Sam Guyer • New assistant professor in CS • Complete Ph.D. in 2003 at University of Texas • Grew up in Boston • Research area: Compilers Mostly, new applications and algorithms

  3. My research • Compilers are powerful tools • Performance improvement • Through program transformation • Better cooperation with run-time system, OS • Error checking • Analyze program behavior • Try to predict errors – eg, null pointer dereference • Try to identify security holes – eg, buffer overrun This problem is wicked hard

  4. Today: Threads • What are they? • Why use ‘em? • Problems – synchronization • Wait, why are we using them? • Off to Dr. Couch’s OneNote presentation…

  5. Why use threads? • Hide latency • Don’t wait for disk access, network transfers, etc • Less overhead than processes • Easier for threads to cooperate than processes • Schedule on multiprocessors • True parallelism • Near future: all processors will have multiple cores • Great, threads are easy, right? • Not so fast…

  6. Synchronization – Motivation • “The too much milk problem” • Example of need to synchronize activities Thanks to Emery Berger UMass Amherst

  7. Increment the value of x by one Example • Consider following routine: int x = 0; void *threaded_routine (void * v) { const int *n = (int *)v; int i; for (i=0; i<10; i++) { int y=x; y++; printf("%d: y=%d\n",*n,y); sleep(1); x=y; printf("%d: x=%d\n",*n,x); } }

  8. Multithreaded • Run three instances • Should produce “30” – three threads increment the value 10 times • How can we fix this?

  9. Solving the Too Much Milk Problem • Correctness properties • Only one person buys milk • Safety: “nothing bad happens” • Someone buys milk if you need to • Progress: “something good eventually happens” • Add some synchronization protocol: • “Leave a note” (lock) • “Remove a note” (unlock) • “Don’t buy milk if there’s a note” (wait)

  10. Too Much Milk: Solution 1 thread A if (no milk && no note) leave note buy milk remove note thread B if (no milk && no note) leave note buy milk remove note too much milk • Does this work?

  11. Too Much Milk: Solution 2 thread A leave note A if (no note B) if (no milk) buy milk remove note A Idea: use labeled notes thread B leave note B if (no note A) if (no milk) buy milk remove note B oops – no milk

  12. Too Much Milk: Solution 3 thread A leave note A while (note B) do nothing if (no milk) buy milk remove note A Idea: wait for the right note thread B leave note B if (no note A) if (no milk) buy milk remove note B • Must try all possibilities to verify

  13. Too Much Milk: Solution 3 thread A leave note A while (note B) do nothing if (no milk) buy milk remove note A Possibility 1: A first, then B thread B leave note B if (no note A) if (no milk) buy milk remove note B • OK

  14. Too Much Milk: Solution 3 Possibility 2: B first, then A thread A leave note A while (note B) do nothing if (no milk) buy milk remove note A thread B leave note B if (no note A) if (no milk) buy milk remove note B • OK

  15. Too Much Milk: Solution 3 thread A leave note A while (note B) do nothing if (no milk) buy milk remove note A Possibility 3: Interleaved – A waits & buys thread B leave note B if (no note A) if (no milk) buy milk remove note B • OK

  16. Too Much Milk: Solution 3 Possibility 4: Interleaved – A waits, B buys thread A leave note A while (note B) do nothing if (no milk) buy milk remove note A thread B leave note B if (no note A) if (no milk) buy milk remove note B • OK

  17. Too Much Milk: Solution 3 Solution 3:“Thread A waits for B, otherwise buys” • Correct – preserves desired properties • Safety: we only buy one milk • Progress: we always buy milk • But…

  18. Problems with this Solution • Complicated • Difficult to convince ourselves that it works • Asymmetrical • Threads A & B are different • Adding more threads = different code for each thread • Poor utilization • Busy waiting – consumes CPU resources, no useful work • Possibly non-portable • Relies on atomicity of loads & stores

  19. Synchronization Terminology Mutual exclusion (“mutex”)– prevents multiple threads from entering Critical section– code only one thread can execute at a time Race condition– outcome of some code is non-deterministic Lock– mechanism for mutual exclusion Atomic or atomicity– either all completes, or none completes

  20. Locks • Provide mutual exclusion to shared data via two atomic routines • Lock::Acquire – wait for lock, then take it • Lock::Release – unlock, wake up waiters • Rules: • Acquire lock before accessing shared data • Release lock afterwards • Lock – initially released

  21. Too Much Milk: Locks thread A Lock.acquire() if (no milk) buy milk Lock.release() thread B Lock.acquire() if (no milk) buy milk Lock.release()

  22. With locks… int x=0; void *threaded_routine (void * v) { const int *n = (int *)v; int i; for (i=0; i<10; i++) { pthread_mutex_lock(&locker); int y=x; y++; printf("%d: y=%d\n",*n,y); sleep(1); x=y; printf("%d: x=%d\n",*n,x); pthread_mutex_unlock(&locker); } }

  23. Locks • Now run three threads… • What have we accomplished? Made the update of x atomic • Clean, symmetric - but how do we implement it?

  24. Implementing Locks • Requires hardware support (in general) • Can build on atomic operations: • Load/Store • Disable interrupts • Uniprocessors only • Test & Set, Compare & Swap

  25. Race conditions • In practice: These are the most difficult bugs you will ever see • Often occur intermittently • Debugging changes the timing, hides the bug • What to do? • Two neat-o approaches • Run-time race detection • Compile-time race detection

  26. Summary • Communication between threads:via shared variables • Critical sections = regions of code that modify or access shared variables • Must be protected by synchronization primitives that ensure mutual exclusion • Loads & stores: tricky, error-prone • Solution: high-level primitives (e.g., locks)

More Related