b3cc concurrency 03 threads

B3CC: Concurrency 03: Threads Trevor L. McDonell Utrecht - PowerPoint PPT Presentation

B3CC: Concurrency 03: Threads Trevor L. McDonell Utrecht University, B2 2020-2021 Announcement The first practical assignment has been released - http://www.cs.uu.nl/docs/vakken/b3cc/assignments.html - Deadline: 2020-11-28 @ 23:59 2


  1. B3CC: Concurrency 03: Threads Trevor L. McDonell Utrecht University, B2 2020-2021

  2. Announcement • The first practical assignment has been released - http://www.cs.uu.nl/docs/vakken/b3cc/assignments.html - Deadline: 2020-11-28 @ 23:59 2

  3. Mutual Exclusion 3

  4. Recall: concurrent access to a global queue head last • Thread A: • Thread B: - Create new object - Set last ->. next to &new - Create new object - Set last ->. next to &new - Set last to &new - Set last to &new 4

  5. Mutual exclusion • Mutual exclusion (locking) protects shared resources - Only one process at a time is allowed to access the critical resource - Modifications to the resource appear to happen atomically • In this lecture: a software approach implementing concurrency control - That is, without relying on builtin language features or hardware support (we’ll cover that later) 5

  6. Software approach to mutual exclusion • Premise - One or more threads with shared memory - Elementary mutual exclusion at the level of memory access • Simultaneous access to the same memory location are serialised • Requirements for mutual exclusion - Only one thread at a time is allowed in the critical section - No deadlock or starvation 6

  7. Attempt #1 • The plan: - Threads take turns executing the critical section - Exploit serialisation of memory access to implement serialisation of access to the critical section • Employ a shared variable (memory location) turn that indicates whose turn it is to enter the critical section P 0 : P 1 : while (turn !!> 0) while (turn !!> 1) //+ do nothing **0 ; //+ do nothing **0 ; <critical section> <critical section> turn = 1; turn = 0; 7

  8. Attempt #1 • Busy waiting (spin lock) - Process is always checking to see if it can enter the critical section - Implements mutual exclusion - Simple • Disadvantages - Process burns resources while waiting - Processes must alternate access to the critical section - If one process fails anywhere in the program, the other is permanently blocked 8

  9. Attempt #2 • The problem: - turn stores who can enter the critical section, rather than whether anybody may enter the critical section • The new plan: - Store for each process whether it is in the critical section right now - flag[i] if process i is in the critical section P 0 : P 1 : while (flag[1]) while (flag[0]) //+ do nothing **0 ; //+ do nothing **0 ; flag[0] = true; flag[1] = true; <critical section> <critical section> flag[0] = false; flag[1] = false; 9

  10. Attempt #2 • If a process fails? - Outside the critical section: the other is not blocked - Inside the critical section: the other is blocked (however, difficult to avoid) • Does it work? 1. Both flags are set to false 2. P 0 enters critical section 3. P 1 enters critical section 4. P 1 sets flag[1] 5. P 0 sets flag[0] - Does not guarantee exclusive access 10

  11. Attempt #3 • The goal: - Remove the gap between toggling the two flags • The new updated plan: - Move setting the flag to before checking whether we can enter P 0 : P 1 : flag[0] = true; flag[1] = true; while (flag[1]) while (flag[0]) //+ do nothing **0 ; //+ do nothing **0 ; <critical section> <critical section> flag[0] = false; flag[1] = false; 11

  12. Attempt #3 • Is it working now? - No. The gap can cause a deadlock now >_> - Deadlock: when each member of a group of processes is waiting for another to take action (e.g. waiting for another to release a lock) 12

  13. Attempt #4 • Previous problem: - Process sets its own state before knowing the other processes’ states, and cannot back off • The new updated revised plan: - Process retracts its decision if it cannot enter P 0 : P 1 : flag[0] = true; flag[1] = true; while (flag[1]) { while (flag[0]) { flag[0] = false; flag[1] = false; delay(); delay(); flag[0] = true; flag[1] = true; } } <critical section> <critical section> flag[0] = false; flag[1] = false; 13

  14. Attempt #4 • Is it working now? - Close, but we may have a livelock =_= - Livelock: The states of the group of processes are constantly changing with regard to each other, but none are progressing (e.g. trying to obtaining a lock, but backing off if it fails) - A special case of resource starvation, and a risk for algorithms which attempt to detect and recover from deadlock 14

  15. Attempt #5 • Improvements - We can solve this problem by combining the fourth and first attempts - In addition to the flag s we use a variable indicating whose turn it is to have precedence in entering the critical section 15

  16. Attempt #5: Peterson’s algorithm • Both processes are courteous and solve a tie in favour of the other • Algorithm can be generalised to work with n processes P 0 : P 1 : flag[0] = true; flag[1] = true; turn = 1; turn = 0; while (flag[1] while (flag[0] &&' turn ==> 1) &&' turn ==> 0) //+ do nothing **0 ; //+ do nothing **0 ; <critical section> <critical section> flag[0] = false; flag[1] = false; 16

  17. Attempt #5: Peterson’s algorithm • Statement: mutual exclusion 
 Threads 0 and 1 are never in the critical section at the same time • Proof: - If P 0 is in the critical section then • flag[0] is true • flag[1] is false OR turn is zero OR P 1 is trying to enter the critical section, after setting flag[1] to true but before setting turn to zero - For both P 0 and P 1 to be in the critical section • flag[0] AND flag[1] AND turn=0 AND turn=1 17

  18. Hardware support • The compare-and-swap (CAS) operation is an atomic instruction which allows mutual exclusion for any number of threads using a single bit of memory - Compares the memory location to a given value - If they are the same, writes a new value to that location - Returns the old value of the memory location https://www.felixcloutier.com/x86/cmpxchg 18

  19. Hardware support • The plan: - Use a bit lock where zero represents unlocked and one represents locked while (atomic_cas(lock, 0, 1) ==> 1) //+ do nothing **0 ; <critical section> lock = 0; • In Haskell we can use atomicModifyIORef’ or atomicModifyIORefCAS (from atomic - primps ) 19

  20. Non-blocking algorithms • Obstruction-freedom - From any point after a thread begins executing in isolation, it finishes in a finite number of steps (a thread will be able to finish if no other thread makes progress) • Lock-freedom - Some method will finish in a finite number of steps • Wait-freedom - Every method will finish in a finite number of steps • Starvation - A process is denied access to a resource. Antonym: fairness 20

  21. Non-blocking algorithms independent dependent dependent non-blocking non-blocking blocking every method Wait-free Obstruction-free Starvation-free makes progress maximal vs. mimimal some method Lock-free Deadlock-free ? makes progress blocking dependent vs. vs. non-blocking independent http://www.cs.tau.ac.il/~shanir/progress.pdf 21

  22. Threads in Haskell 22

  23. Threads • The fundamental action in concurrency: create a new thread of control forkIO ::; IO () ->. IO ThreadId - Takes a computation of type IO () as its argument - This IO action executes in a new thread concurrently with other threads - No specified order in which threads execute - Threads are very cheap: ~1.5 Kb / thread, easily run thousands of threads 23

  24. Example • Interleaving of two threads import Control.Concurrent import Control.Monad main ::; IO () main = do let n = 1000 forkIO $ replicateM_ n (putChar 'A') forkIO $ replicateM_ n (putChar 'B') return () 24

  25. Example • Interleaving of two threads - The term n ::; Int is shared between both threads (captured); this is safe because it is immutable - The program exits when main returns, even if there are other threads still running! • How to check whether the child thread has completed? 25

  26. tot ziens Photo by Ugur Arpaci

Recommend


More recommend


Explore More Topics

Stay informed with curated content and fresh updates.