Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 6: Monitors & Semaphores. Monitor Contains data and procedures needed to allocate shared resources Accessible only within the monitor No way for.

Similar presentations


Presentation on theme: "Lecture 6: Monitors & Semaphores. Monitor Contains data and procedures needed to allocate shared resources Accessible only within the monitor No way for."— Presentation transcript:

1 Lecture 6: Monitors & Semaphores

2 Monitor Contains data and procedures needed to allocate shared resources Accessible only within the monitor No way for threads outside monitor to access monitor data Resource allocation using Monitors Thread must call monitor entry routine Mutual exclusion is rigidly enforced at monitor boundary A thread that tries to enter monitor when it is in use must wait Monitor Operating Systems - Deitel & Associates - 2004

3 lock( ) vs. monitor( ) Both lock( ) and monitor( ) are methods of enforcing mutual exclusion in modern programming languages such as C# and Java. In the.NET environment, lock( ) is preferred since it manages the thread queue. Like the lock keyword, monitors prevent blocks of code from simultaneous execution by multiple threads. The Enter method allows one and only one thread to proceed; all other threads are blocked until the executing thread calls Exit. This is just like using the lock keyword. In fact, the lock keyword is implemented with the Monitor class. Using the lock is generally preferred over using the Monitor class directly, both because lock is more concise, and because lock ensures that the underlying monitor is released, even if the protected code throws an exception. This is accomplished with the finally keyword, which executes its associated code block regardless of whether an exception is thrown. http://msdn.microsoft.com/en-us/library/ms173179%28VS.80%29.aspx

4 using System; using System.Threading; namespace monitor_demo_02 { public class Test { static int count = 0; static void Main() { ThreadStart job = new ThreadStart(ThreadJob); Thread thread = new Thread(job); thread.Start(); for (int i = 0; i < 5; i++) { int tmp = count; Console.WriteLine("Read count={0}", tmp); Thread.Sleep(50); tmp++; Console.WriteLine("Incremented tmp to {0}", tmp); Thread.Sleep(20); count = tmp; Console.WriteLine("Written count={0}", tmp); Thread.Sleep(30); } thread.Join(); Console.WriteLine("Final count: {0}", count); Console.ReadKey(); } Multi-Threaded Demo no Monitor http://www.yoda.arachsys.com/csharp/multithreading.html

5 static void ThreadJob() { for (int i = 0; i < 5; i++) { int tmp = count; Console.WriteLine("\t\t\t\tRead count={0}", tmp); Thread.Sleep(20); tmp++; Console.WriteLine("\t\t\t\tIncremented tmp to {0}", tmp); Thread.Sleep(10); count = tmp; Console.WriteLine("\t\t\t\tWritten count={0}", tmp); Thread.Sleep(40); } Multi-Threaded Demo - concluded

6 Read count=0 Incremented tmp to 1 Written count=1 Incremented tmp to 1 Written count=1 Read count=1 Incremented tmp to 2 Read count=1 Written count=2 Read count=2 Incremented tmp to 2 Incremented tmp to 3 Written count=2 Written count=3 Read count=3 Incremented tmp to 4 Written count=4 Incremented tmp to 4 Written count=4 Read count=4 Incremented tmp to 5 Written count=5 Incremented tmp to 5 Written count=5 Read count=5 Incremented tmp to 6 Written count=6 Final count: 6 Multi-Threaded Sample Output

7 using System; using System.Threading; namespace monitor_demo_01 { public class Test { static int count = 0; static readonly object countLock = new object(); static void Main() { ThreadStart job = new ThreadStart(ThreadJob); Thread thread = new Thread(job); thread.Start(); for (int i = 0; i < 5; i++) { Monitor.Enter(countLock); int tmp = count; Console.WriteLine("Read count={0}", tmp); Thread.Sleep(50); tmp++; Console.WriteLine("Incremented tmp to {0}", tmp); Thread.Sleep(20); count = tmp; Console.WriteLine("Written count={0}", tmp); Monitor.Exit(countLock); Thread.Sleep(30); } thread.Join(); Console.WriteLine("Final count: {0}", count); Console.ReadKey(); } Monitor Demo

8 static void ThreadJob() { for (int i = 0; i < 5; i++) { Monitor.Enter(countLock); int tmp = count; Console.WriteLine("\t\t\t\tRead count={0}", tmp); Thread.Sleep(20); tmp++; Console.WriteLine("\t\t\t\tIncremented tmp to {0}", tmp); Thread.Sleep(10); count = tmp; Console.WriteLine("\t\t\t\tWritten count={0}", tmp); Monitor.Exit(countLock); Thread.Sleep(40); } Monitor Demo - concluded

9 Read count=0 Incremented tmp to 1 Written count=1 Read count=1 Incremented tmp to 2 Written count=2 Read count=2 Incremented tmp to 3 Written count=3 Read count=3 Incremented tmp to 4 Written count=4 Read count=4 Incremented tmp to 5 Written count=5 Read count=5 Incremented tmp to 6 Written count=6 Read count=6 Incremented tmp to 7 Written count=7 Read count=7 Incremented tmp to 8 Written count=8 Read count=8 Incremented tmp to 9 Written count=9 Read count=9 Incremented tmp to 10 Written count=10 Final count: 10 Monitor Demo Sample Output

10 Semaphores Software construct that can be used to enforce mutual exclusion Contains a protected variable Can be accessed only via wait and signal commands Also called P and V operations, respectively Semaphores

11 Binary semaphore: allow only one thread in its critical section at any time... Wait operation If no threads are waiting, allow thread into its critical section Decrement protected variable (to 0 in this case) Otherwise place in waiting queue Signal operation Indicate that thread is outside its critical section Increment protected variable (from 0 to 1) A waiting thread (if there is one) may now enter Binary Semaphore

12 Counting semaphores Initialized with values greater than one Can be used to control access to a pool of identical resources Decrement the semaphore’s counter when taking resource from pool Increment the semaphore’s counter when returning it to pool If no resources are available, thread is blocked until a resource becomes available Counting Semaphores

13 Semaphores A semaphore is a protected variable whose value can be accessed and altered only by the operations P( ) and V( ) and an initialization operation SemaphoreInit( ). Binary semaphores can have values true or false while counting semaphores can have non- negative integer values. function P(S:semaphore) if S>0 then S:=S-1; else wait_for(S); end if; end P; function V(S:semaphore) if waiting_for(S) then release_for(S); else S:=S+1; end if; end V; wait_for(S) adds the process calling P(S) to a queue. waiting_for(S) is a boolean function that checks to see if the queue is empty. release_for(S) releases the process waiting at the front of the queue.

14 Using Semaphores: Mutual Exclusion program example_one is active : semaphore; procedure P1 is begin while true do begin stuff; P(active); critical_region; V(active); end; end P1; procedure P2 is begin while true do begin stuff; P(active); critical_region; V(active); end; end P2; begin example_one semaphore_init(active,1); parbegin P1; P2; parend; end example_one; The semaphore active is set to one (1) and acts to control the process’s access to its critical section.

15 Using Semaphores: Producer-Consumer Interprocess communication occurs when one process passes data to another process. This is more complex than a procedure call with parameter passing since the two processes do not necessarily share the same address space. The processes must be synchronized which means that the data transfer must occur in the proper time sequence. procedure producer is nextvalue : integer; begin while true do begin calculate(nextvalue); P(access_numbuffer); numbuffer:=nextvalue; V(access_numbuffer); V(numbuffer_loaded); end; end producer; procedure consumer is nextvalue : integer; begin while true do begin P(numbuffer_loaded); P(access_numbuffer); nextvalue:=numbuffer; V(access_numbuffer); make_use_of(nextvalue); end; end consumer;

16 Mutual Exclusion with Test-and-Set When the computer hardware can be used to support the enforcement of mutual exclusion, the complexity of the resulting software is greatly reduced. The indivisible instruction testandset(a,b) reads the value of a boolean b, copies it into a and then sets b to true all within the span of a single uninterruptible instruction. procedure P1 no_P1 : boolean; begin while true do begin no_P1:=true; while no_P1 do testandset(no_P1,go); critical_region; go:=false; other_stuff; end; end P1; procedure P2 no_P2 : boolean; begin while true do begin no_P2:=true; while no_P2 do testandset(no_P2,go); critical_region; go:=false; other_stuff; end; end P2;

17 Summary Monitors hold data to be protected from concurrent asynchrononous access Monitors can be used to manage shared resources of any type In C# lock( ) is preferred when enforcing mutual exclusion of shared data Semaphores require special hardware implementation (binary and counting) Test-and-Set is an uninteruptable instruction


Download ppt "Lecture 6: Monitors & Semaphores. Monitor Contains data and procedures needed to allocate shared resources Accessible only within the monitor No way for."

Similar presentations


Ads by Google