threads & synchronization, conclusion
DESCRIPTION
Threads & Synchronization, Conclusion. Vivek Pai Nov 20, 2001. Mechanics. Read Birrell’s paper – future use I’ll send out a link via e-mail Next time: basic networking, IPC Some readings already listed, maybe more in e-mail Now: wrap up threads, critical sections - PowerPoint PPT PresentationTRANSCRIPT
Threads & Synchronization, Conclusion
Threads & Synchronization, Conclusion
Vivek PaiNov 20, 2001
2
MechanicsMechanics
Read Birrell’s paper – future useI’ll send out a link via e-mail
Next time: basic networking, IPCSome readings already listed, maybe more in e-mail
Now: wrap up threads, critical sections Also – quiz 3 graded, working on current grades
3
Big Picture on SynchronizationBig Picture on Synchronization
Why do we need it?We have multiple things runningThey perform read/write sharing of data
Can we avoid synchronization?Eliminate shared dataPerform read-only sharingEliminate parallel execution
4
Synchronization PrimitivesSynchronization Primitives Why so many?
Different mechanisms for different situationsConvenient for programmers
Can we have fewer?Most can be built from “first principles”Reinvention error-prone and time-consuming
How do you decide?Analysis or Idiom
5
Primitives and PurposesPrimitives and Purposes Locks
One holder, maybe lots of waiters Semaphores
Possibly lots of holders, lots of waiters Barriers
Wait until everyone catches up Condition variables
Waiters block, signal everyone when some condition occurs Monitors
Expresses synchronization at a high level
6
Continuing on SynchronizationContinuing on Synchronization
So far, we’ve seen “Spinning” on lock during entire critical section Disabling interrupts for critical section (bad) Queue associated with each lock & blocking System calls for locking – possibly blocking
Since system calls exist, is everything solved?Assume shared variable “count”Lock(&mutex); count++; Unlock(&mutex);
7
Cost of Protecting a Shared VariableCost of Protecting a Shared Variable
Making lock system callPushing parameter, sys call # onto stackGenerating trap/interrupt to enter kernel
System call in kernelJump to appropriate function in kernelVerify process passed in valid pointer to mutexDo locking operation, block process if needed
Actually change count – load/modify/store System call again to release mutex
8
What is Lock Contention?What is Lock Contention? Competition for a lock
Uncontended = rarely in use by someone elseContended = often used by someone elseHeld = currently in use by someone
Question: what do these combinations do?Spinning on low-contention lockSpinning on high-contention lockBlocking on low-contention lockBlocking on high-contention lock
9
Things to PonderThings to Ponder
If critical section is just “count++;”, what is the overhead of the synchronization
Is there some other way of doing this?
What if you don’t know how long the critical section will be?
10
What If You Have the FollowingWhat If You Have the Following
Test-and-set – works at either user or kernel
System calls for block/unblockBlock takes some token and goes to sleepUnblock “wakes up” a waiter on token
11
User-Level Acquire/Release using Block and Unblock
User-Level Acquire/Release using Block and Unblock
In what scenarios is this scheme appropriate? Where should it not be used?
12
Semaphores (Dijkstra, Semaphores (Dijkstra, 1965)1965) Down or “P”
AtomicWait for semaphore to become positive and then decrement by 1
P(s) { if (--s < 0) Block(s);}
V(s) { if (++s <= 0) Unblock(s);}
• Up or “V”– Atomic
– Increment semaphore by 1 wake up a waiting P if any
13
Bounded Buffer Bounded Buffer (Consumer-Producer)(Consumer-Producer) Example:
grep vivek access.log | more
Producer Consumer
14
Bounded Buffer w/ Bounded Buffer w/ SemaphoresSemaphoresmutex = 1emptyCount = N;fullCount = 0;
producer() { while (1) { produce an item P(emptyCount);
P(mutex); put the item in buffer V(mutex);
V(fullCount); }}
consumer() { while (1) { P(fullCount);
P(mutex); take an item from buffer V(mutex);
V(emptyCount); consume the item }}
15
Implementing General SemaphoresImplementing General Semaphores
Need a mutex for each semaphore Block and Unblock need to release mutex after
entering their critical sectionP(s) { Acquire(s.mutex); if (--s.value < 0) Block(s); else Release(s.mutex)}
V(s) { Acquire(s.mutex); if (++s.value <= 0) Unblock(s); else Release(s.mutex)}
16
Implement General Implement General Semaphores Semaphores with Acquire/Releasewith Acquire/Release
Kotulski (1988)Two processes call P(s) (when s.value is 0) and preempted after Release(s.mutex)Two other processes call V(s)
P(s) { Acquire(s.mutex); if (--s.value < 0) { Release(s.mutex); Acquire(s.delay); } else Release(s.mutex);}
V(s) { Acquire(s.mutex); if (++s.value <= 0) Release(s.delay); Release(s.mutex);}
17
Hemmendinger’s Solution (1988)
The idea is not to release s.mutex and turn it over individually to the waiting process
P and V are executing in lockstep
P(s) { Acquire(s.mutex); if (--s.value < 0) { Release(s.mutex); Acquire(s.delay); } Release(s.mutex);}
V(s) { Acquire(s.mutex); if (++s.value <= 0) Release(s.delay); else Release(s.mutex);}
18
Kearns’s Solution (1988)
P(s) { Acquire(s.mutex); if (--s.value < 0) { Release(s.mutex); Acquire(s.delay); Acquire(s.mutex); if (--s.wakecount > 0) Release(s.delay); } Release(s.mutex);}
V(s) { Acquire(s.mutex); if (++s.value <= 0) { s.wakecount++; Release(s.delay); } Release(s.mutex);}
Two Release( s.delay) calls are also possible
19
Hemmendinger’s Correction (1989)P(s) { Acquire(s.mutex); if (--s.value < 0) { Release(s.mutex); Acquire(s.delay); Acquire(s.mutex); if (--s.wakecount > 0) Release(s.delay); } Release(s.mutex);}
V(s) { Acquire(s.mutex); if (++s.value <= 0) { s.wakecount++; if (s.wakecount == 1) Release(s.delay); } Release(s.mutex);}
Correct but a complex solution
20
Hsieh’s Solution (1989)
Use Acquire(s.delay) to block processes Correct but still a constrained implementation
P(s) { Acquire(s.delay); Acquire(s.mutex); if (--s.value > 0) Release(s.delay); Release(s.mutex);}
V(s) { Acquire(s.mutex); if (++s.value == 1) Release(s.delay); Release(s.mutex);}
21
Definition TimeDefinition Time What’s a semaphore?
OED says signaling mechanism using flags, especially used for rail and sea
What’s a monitor? Is itA device to watch a signal without disrupting itA person who watches, enforces, etcA programming-language construct for exclusionA giant lizard
22
Answer: All of the AboveAnswer: All of the Above
Up to 6.5 feet long Thought to alert for the presence of crocodiles
23
Natural Habitat of the MonitorNatural Habitat of the Monitor
The Mesa systemXerox PARC (Palo Alto Research Center)– Cool place– Lots of neat stuff developed there
Digital SRCExodus of people from PARCLanguage, parallelism focus
24
Motivation
What we wantDequeue(q) blocks until q is not empty
Semaphores are difficult to use: orders are important
Enqueue(q, item){ Acquire(mutex); put item into q; Release(mutex);}
Dequeue(q){ Acquire(mutex); take an item from q; Release(mutex); return item;}
25
Think About Critical SectionsThink About Critical Sections
What are they?Pieces of code in the parallel environment
What makes code a critical section?Correctness constraints, ultimatelyBut really, what makes code a critical section?
Is there some way to take advantage of this?If so, when?
26
Answer – Push It To The CompilerAnswer – Push It To The Compiler
Easier on programmer Compiler gets it right once
Programmer gets it wrong often Information available at compile-time Small amount of programmer annotation
27
Monitor Hides Mutual Exclusion Procedures are
mutually exclusive Shareddata
...
Queue of waiting processestrying to enter the monitor
procedures
28
Condition Variables in A Monitor
Wait( condition )Block on “condition”
Signal( condition )Wakeup a blocked process on “condition”
Conditions are not “sticky”
Shareddata
...Entry queue
operations
xy
Queues associatedwith x, y conditions
29
Producer-Consumer with Monitorsmonitor ProdCons condition full, empty;
procedure Enter; begin if (the queue is full) wait(full); put item into buffer; if (only one item) signal(empty); end; procedure Remove; begin if (buffer is empty) wait(empty); remove an item; if (buffer was full) signal(full); end;
procedure Producerbegin while true do begin produce an item ProdCons.Enter(); end;end;
procedure Consumerbegin while true do begin ProdCons.Remove(); consume an item; end;end;
30
Wow, This Looks Like Cake!Wow, This Looks Like Cake!
Well, the language/compiler has to support it One problem – what happens on wakeup?
Only one thing can be inside monitorWakeup implies signaller, waiter in monitor
31
Options of the SignalerOptions of the Signaler Exit the monitor (Hansen) Relinquishes control to the awaken process and suspend
the current one (Hoare)Complex if the signaler has other work to toTo make sure there is no work to do is difficult because the signal implementation is not aware how it is usedIt is easy to prove things
Continues its execution (Mesa)Easy to implementBut, the condition may not be true when the awaken process actually gets a chance to run
32
Mesa Style “Monitor”(Birrell’s Paper) Acquire and Release Wait( lock, condition )
Atomically unlock the mutex and enqueued on the condition variable (block the thread)Re-lock the lock when it is awaken
Signal( condition )Noop if there is no thread blocked on the condition variableWake up at least one if there are threads blocked
Broadcast( condition )Wake up all
33
Example Add an item to the queue
Acquire( mutex );add an item to the queue;Signal( nonEmptyCond );Release( mutex );
Remove an item from a queueAcquire( mutex );while ( queue is empty )
Wait( mutex, nonEmptyCond );remove an item;Release( mutex );
Question: Can “while” be replaced by “if”
34
Mesa-Style vs. Hoare-Style Monitor Mesa-style
Signaller keeps lock and CPUWaiter simply put on ready queue, with no special priority
Hoare-styleSignaller gives up lock and waiter runs immediatelyWaiter gives lock and CPU back to signaller when it exits critical section or if it waits again
35
Condition Variables PrimitivesCondition Variables Primitives Wait( mutex, cond )
Enter the critical section (min busy wait) Release mutexPut my PCB to cond’s queueCall schedulerExit the critical sectionAcquire mutex
• Signal( cond )– Enter the critical section
(min busy wait)
– Wake up one PCB in cond’s queue
– Exit the critical section
36
Are Monitors Alive Today?Are Monitors Alive Today? Actual monitors were fairly dead
Java resurrected them What killed the monitor?
Man encroached on their environment – just kiddingLanguage support a real dead weightC kills everything not-C
But they still exist, sort ofCondition variables, etc., used heavily