My Profile
Gifts
Active Members
TodayLast 7 Days
more...
|
Thread Communication Using Wait(), Pulse() and PulseAll()
Posted Date: 10 Jun 2004 Resource Type: Articles Category: .NET Framework
|
Posted By: ANITA MARY JOSEPH Member Level: Gold Rating: Points: 10
|
The resource has not been reviewed by Editors yet. Readers are advised to use their best judgement before accessing this resource. This resource will be reviewed shortly. If you think this resource contain inappropriate content, please report to webmaster. |
So far we’ve learned the basics of Multithreaded programming. And I hope now all of you are familiar with starting a thread, locking a block of code and so on….
Are you a New Member? Alright don’t worry, let me take you to my First Article on Multithreaded Programming: Click Here!
Others GET READY! Let’s Start with Thread Communication.
Consider the following situation. A Thread called T is executing inside a lock block and needs access to a resource, called R, that is temporarily unavailable. What should T do???? A Good Solution is to have T temporarily relinquish control of the object, allowing another thread to run. When R becomes Available, T can be notified and resume execution. Such an approach relies upon some form of inherited communication in which one thread can notify another that it is blocked, and be notified when it can resume execution.
So see how important it is to have threads communicate with each other…
C# supports interthread communication with the Wait(), Pulse(), and PulseAll() methods. Note: These methods are defined by the Monitor class and can be called only from within a locked block of code. Here is how they are used. When a thread is temporarily blocked from running, it calls Wait() This causes the thread to go to sleep and the lock for that object to be released, allowing another thread to use the object. At a later point, the sleeping thread is awakened when some other thread enters the same lock and calls Pulse() or PulseAll(). A call to Pulse() resumes the first thread in the queue of threads waiting for the lock. A call to PulseAll signals the release of the lock to all waiting threads.
Here are two commonly used forms of Wait():
public static bool Wait(object waitObject) public static bool Wait(object waitObject, int milliseconds)
The first form waits until notified. The second form waits until notified or until the specified period of milliseconds has expired. For both waitObject specifies the object upon which to wait.
Here are the general forms for Pulse() and PulseAll():
public static void Pulse(object waitObject) public static void PulseAll(object waitObject)
Here, waitObject is the object being released.
Note: A SynchronizationLockException will be thrown if Wait(), Pulse or PulseAll() is called from code that is not within a lock block.
Example: To understand the need for and the application of Wait() and Pulse(), Let’s create A program that simulates the bouncing of a ball by displaying the words “Ping” and “Pong” on the screen.
// Using Wait() and Pulse() to create a bouncing ball. using System; using System.Threading;
class PingPong { public void ping( bool running ) { lock(this) { if(!running) { //ball halts. Monitor.Pulse(this); // notify any waiting threads return; } Console.Write("Ping "); Monitor.Pulse(this); // let pong() run Monitor.Wait(this); // wait for pong() to complete } } public void pong( bool running ) { lock(this) { if(!running) { //ball halts. Monitor.Pulse(this); // notify any waiting threads return; } Console.WriteLine("Pong "); Monitor.Pulse(this); // let ping() run Monitor.Wait(this); // wait for ping() to complete } } }
class MyThread { public Thread thread; PingPong pingpongObject;
//construct a new thread.
public MyThread(string name, PingPong pp) { thread = new Thread(new ThreadStart(this.run)); pingpongObject = pp; thread.Name = name; thread.Start(); }
//Begin execution of new thread. void run() { if (thread.Name == "Ping") { for (int i = 0; i < 5; i++) pingpongObject.ping(true); pingpongObject.ping(false);
} else { for (int i = 0; i < 5; i++) pingpongObject.pong(true); pingpongObject.pong(false); } } }
class BouncingBall { public static void Main() { PingPong pp = new PingPong(); Console.WriteLine("The Ball is dropped... \n");
MyThread mythread1 = new MyThread("Ping", pp); MyThread mythread2 = new MyThread("Pong", pp);
mythread1.thread.Join(); mythread2.thread.Join(); Console.WriteLine("\nThe Ball Stops Bouncing."); Console.Read(); } }
Here’s the output:
The Ball is dropped...
Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong
The Ball Stops Bouncing.
Let me end this article with a note on Deadlock.
Deadlock
What’s Deadlock??? Well Deadlock is, as the name implies, a situation in which one thread is waiting for another thread to do something, but that other thread is waiting on the first. Thus both threads are suspended, waiting for each other, and neither executes. Often the cause of the deadlock is not readily understood just by looking at the source code of the program, because concurrently executing threads can interact in complex ways at runtime. To avoid deadlock, careful programming and thorough testing are required. In general, if a multithreaded program occasionally “hangs”, deadlock is the likely cause.
|
Responses
|
No responses found. Be the first to respond and make money from revenue sharing program.
|
|
|