Mutex [c #]
You can synchronize between threads and across processes using Mutex objects. Although Mutex does not have all the wait and pulse features of the Monitor class, it is indeed a function of creating a named mutex between the processes.
Call Waitone, Waitall or Waitany can request Mutex's authority. If no thread has it, the state of Mutex is the status of the signal.
If a thread has Mutex, the thread can specify the same MUTEX in the repeated wait - request call, without having to block its execution; however, it must release MUTEX that is the same as the release of the authority.
If a thread is terminated normally when you have Mutex, the status of Mutex will be set to the status of the signal, and the next wait thread will acquire the power. The Mutex class corresponds to the Win32 CreateMutex call.
The following C # code example illustrates the use of MUTEX.
[C #]
Using system;
Using system.threading;
Public class mutexsample {
STATIC MUTEX GM1;
STATIC MUTEX GM2;
Const int iters = 100;
Static AutoreteEvent Event1 = New AutoSetEvent (false);
Static AutoResevent Event2 = New AutoreteEvent (False);
Static AutoreteEvent Event3 = New AutoSetEvent (false);
Static AutoReleaseTevent Event4 = New AutoreteEvent (False);
Public static void main (String [] args) {
Console.writeLine ("MutexSample.cs ...");
GM1 = New Mutex (True, "MyMutex");
// CREATE MUTEXT INITIALOWNED, with NAME OF "MyMutex".
GM2 = New Mutex (TRUE);
// CREATE MUTEXT INITIALOWNED, with no name.
Console.writeLine ("- Main Owns GM1 and GM2);
AutoreteEvent [] EVS = New AutoReveTevent [4];
EVS [0] = EVENT1;
// Event for t1.
EVS [1] = Event2;
// Event for t2.
EVS [2] = EVENT3;
// Event for t3.
EVS [3] = Event4;
// Event for t4.
MutexSample TM = new mutexsample ();
Thread T1 = New Thread (New ThreadStart (TM.T1Start);
Thread T2 = New Thread (New ThreadStart (TM.T2Start);
Thread T3 = New Thread (New ThreadStart (TM.T3Start);
Thread T4 = New Thread (New ThreadStart (TM.T4Start); t1.start ();
// Calls Mutex.waitall (Mutex [] of GM1 and GM2).
T2.Start ();
// Calls Mutex.waitone (Mutex GM1).
T3.Start ();
// Calls Mutex.waitany (Mutex [] of GM1 and GM2).
T4.Start ();
// Calls Mutex.waitone (Mutex GM2).
Thread.sleep (2000);
Console.writeline ("- main releases gm1");
gm1.releasemutex ();
// t2 and t3 will end and signal.
Thread.sleep (1000);
Console.Writeline ("- main releases GM2");
gm2.releasemutex ();
/// t1 and t4 will end and signal.
Waithandle.waitall (EVS);
// Waiting UnsiL All Four Threads Signal That They Are Done.
Console.writeline ("... mutexsample.cs");
}
Public void t1start () {
Console.writeLine ("T1start Started, Mutex.waitall (Mutex [])")
Mutex [] GMS = New Mutex [2];
GMS [0] = GM1;
// Create and Load An Array of Mutex Objects for Waitall Call.
GMS [1] = GM2;
Mutex.waitall (GMS);
// Waits Until Both Mutex Objects Are Released.
Thread.sleep (2000);
Console.writeline ("T1Start Finished, Mutex.waitall (Mutex [])");
Event1.set ();
// AutoResetEvent.Set () Flagging Method is Done.
}
Public void t2start () {
Console.writeLine ("T2Start Started, GM1.Waitone ()");
Gm1.waitone ();
// Waits Until Mutex GM1 is Released.
Console.writeLine ("T2Start Finished, GM1.Waitone ()");
Event2.set ();
// AutoResetEvent.Set () Flagging Method is Done.
}
Public void t3start () {
Console.writeline ("T3Start Started, Mutex.waitany");
Mutex [] GMS = New Mutex [2];
GMS [0] = GM1;
// Create and Load an Array of Mutex Objects for Waitany Call.
GMS [1] = GM2;
Mutex.waitany (GMS);
// Waits Until Either Mutex Object Is Released.console.writeline ("T3Start Finished, Mutex.waitany");
Event3.set ();
// AutoResetEvent.Set () Flagging Method is Done.
}
Public void t4start () {
Console.writeline ("T4start Started, GM2.Waitone ()");
gm2.waitone ();
// Waits Until Mutex GM2 is released.
Console.writeline ("T4Start Finished, GM2.Waitone ()");
Event4.set ();
// AutoResetEvent.Set () Flagging Method is Done.
}
}
Interlocked [C #]
Interlocked method CompareExchange, Decrement, Exchange, and Increment provide a simple mechanism to synchronize access to variables shared by multiple threads. If the variable is located in a shared memory, the thread of the different processes can use this mechanism.
The increment and Decrement functions will increment or decremented the variable combination with the operation of the check result value. This atomic operation is very useful for multi-tasking operating systems. In this operating system, the system can interrupt a thread execution to grant another thread to another thread. If there is no such synchronization, a thread may be interrupted before the result value of the variable is incremented but has not been able to check the result value of the variable. The second thread can then increase the same variable. When the first thread receives its next time piece, it will check the value of the variable, and now this value has been incremented twice instead of once. The interlocked variable access function prevents such an error.
The Exchange function automatically exchanges the value of the specified variable. The CompareExchange function combines two operations: compare two values and store the third value in one of the variables based on the results of the comparison.
In modern processors, the method of the Interlocked class can usually be implemented by a single instruction. In this way, the method of the Interlocked class provides high performance synchronization and can be used to generate higher level synchronization mechanisms such as a rotary lock.
The Exchange and CompareExchange methods disclosed in Interlocked use parameters that can store the referenced Object type. However, type safety requirements are strictly type all parameters to object; the objects cannot be simply converted to Object in the call to one of the methods. In other words, you must create a variable of the object type, assign the custom object to the variable, and then pass the variable. The following simple C # code example will only allow this property to be set to be set using a single call.
[C #]
Private Object_x;
Public propers x {
Set (x value) {
Object ovalue = value;
Interlocked.comPareExchange (Ref x, ovalue, null);
}
Get () {
Return (X )_X;
}
}
Readerwriterlock
ReaderWriterlock defines a lock of single writer / multiple readers. ReaderWriterlock:
The overhead is very low enough to use a lot of use (such as synchronization for each object).
Try to seek balance between writers and readers. Once the writer lock is requested, no new reader will be accepted until the writer has access to access. Writer and readers are not permanently refused to access. Support timeout, this is a very valuable function for detecting deadlocks.
Support event cache. This allows events to move from the area where the content is the largest area to the largest level. In other words, the number of threads in the process limits the number of events needed for reader locks or writer locks.
Supports locks with readers and writers.
Supports rotation counts to avoid context switching on multiprocessor computers.
Support to upgrade the return parameters in the middle of the instruction to upgrade to the writer lock and degrade the status of the lock from the writer lock to restore the lock.
Support for the function of calling the application code release lock. RestoreLock restores the status and instructs the middle writing operation.
Recovered from the most common failures (such as creating event failures). In other words, the interior state of the lock maintenance is not available.