You mayIn the previous articleArticleMedium "href =" http://www.cnblogs.com/LoveJenny/archive/2011/05/28/2060872.html "target =" _ blank "> deep dive into the 12 series of multithreading: bidirectional signals and CompetitionsNote This mode: TwoWaitingThe following structures are required for loops:
Lock (_ Locker)
{
While ( ! _ Flag) monitor. Wait (_ locker );
_ Flag = False ;
}
Here_ FlagSetTrue. This is, in terms of its role, here we are imitatingAutoresetevent. If we_ Flag = false;Then we get a basicManualresetevent.
Let's useWaitAndPulseLaiweiManualreseteventComplete the remainingCodeRight.
Readonly Object _ Locker = New Object ();
Bool _ Signal;
void waitone ()
{< br> lock (_ locker)
{< br> while ( ! _ signal) Monitor. wait (_ locker);
}< BR >}
void set ()
{< br> lock (_ locker) {_ signal = true ; monitor. pulseall (_ locker) ;}< BR >}
VoidReset (){Lock(_ Locker) _ signal= False;}
Use it herePulseallBecause there may be many blocked threads.
IfWaitoneAdd in Method_ Signal = falseYou can simply simulateAutoresetevent.For example:
Void Waitone ()
{
Lock (_ Locker)
{
While ( ! _ Signal) monitor. Wait (_ locker );
_ Signal = False ; // Enable Automatic shutdown | Yes
}
}
Then Set Method, Set Pulseall Change Pulse
Lock (_ locker) {_ signal = true; monitor.Pulse(_ Locker );}
If the int type is used_ SignalThen we can get the most basicSemaphore.
Waiting queues and pulseall
When a redundant thread waits on the same object "Waiting queue(Waiting queue )"It is formed.
Each callPulseWill be released in"Waiting queue"A thread in the header. The following figure shows this:
Thread callMonitor. EnterEnterReadyqueue.Wait for the lock to be obtained. After the lock is obtained successfully, if the lock is executed normally, it will be called later.Monitor. ExitExit,
Otherwise, if you find that you need to wait for other threads or other blocking conditions after obtaining the lock, callWaitMethod to enter the waiting queue,
When the waiting thread is completed and calledPulseAfterWaitingqueueThe thread in the header isPulseWaitCPUScheduling . Then enter againReady queueTo obtain the lock again.
Countdown
WithWaitAndPulse, We can achieveCountdownevent. For example:
Class Countdown
{
Object _ Locker = New Object ();
Int _ Value; // Use _ value to count
Public Countdown (){}
Public Countdown ( Int Initialcount) {_ value = Initialcount ;}
Public Void Singnal () {addcount ( - 1 );} // Reduce the count by one
Public Void Addcount ( Int Amount)
{
Lock (_ Locker)
{
_ Value + = Amount; // Increase or decrease the count
If (_ Value <= 0 ) Monitor. pulseall (_ locker ); // If value <= 0, all the waiting tasks are completed.
}
}
Public Void Wait ()
{
Lock (_ Locker)
{
// Wait as long as the Count is greater than 0.
While (_ Value > 0 )
{
Monitor. Wait (_ locker );
}
}
}
}
This is almost the same as our last code, but this time our blocking condition is based on an integer_ ValueFlag.
References:
Http://www.albahari.com/threading/
CLR via C #3.0