Are condition variables & monitors used in C#?
Can someone give me an example?
Creating and destroying condition variables A condition variable is created by calling the pthread_cond_init subroutine. You may specify a condition attributes object. If you specify a NULL pointer, the condition variable will have the default attributes.
Condition variables allow us to synchronize threads via notifications. So, you can implement workflows like sender/receiver or producer/consumer. In such a workflow, the receiver is waiting for the sender's notification. If the receiver gets the notification, it continues its work.
There are only two operations that can be applied to a condition variable: wait and signal.
condition_variable::wait wait causes the current thread to block until the condition variable is notified or a spurious wakeup occurs, optionally looping until some predicate is satisfied (bool(stop_waiting()) == true).
This version atomically unlocks a Mutex or ReaderWriterLockSlim while waiting for signalling, and relocks it before returning - which is the posix way.
using System.Collections.Concurrent;
namespace System.Threading.More {
public class ConditionVariable {
private readonly ConcurrentQueue<ManualResetEventSlim> _waitingThreads = new ConcurrentQueue<ManualResetEventSlim>();
/// <summary>
/// Atomically unlocks and waits for a signal.
/// Then relocks the mutex before returning
/// </summary>
/// <param name="mutex"></param>
public void Wait(Mutex mutex) {
if (mutex == null) {
throw new ArgumentNullException("mutex");
}
var waitHandle = new ManualResetEventSlim();
try {
_waitingThreads.Enqueue(waitHandle);
mutex.ReleaseMutex();
waitHandle.Wait();
} finally {
waitHandle.Dispose();
}
mutex.WaitOne();
}
public void WaitRead(ReaderWriterLockSlim readerWriterLock) {
if (readerWriterLock == null) {
throw new ArgumentNullException("readerWriterLock");
}
var waitHandle = new ManualResetEventSlim();
try {
_waitingThreads.Enqueue(waitHandle);
readerWriterLock.ExitReadLock();
waitHandle.Wait();
} finally {
waitHandle.Dispose();
}
readerWriterLock.EnterReadLock();
}
public void Signal() {
ManualResetEventSlim waitHandle;
if (_waitingThreads.TryDequeue(out waitHandle)) {
waitHandle.Set();
}
}
public void Broadcast() {
ManualResetEventSlim waitHandle;
while (_waitingThreads.TryDequeue(out waitHandle)) {
waitHandle.Set();
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With