C # multithreaded Learning (vi) How the mutex controls the connection of multiple threads to each other, does not create conflicts and duplicates, requires the use of mutex objects, namely: The Mutex class in the System.Threading namespace. We can think of a mutex as a taxi and a passenger as a thread. Passengers first wait for the bus, then get on the bus and finally alight. When a passenger is in the car, the other passengers are only allowed to get on when he gets off the bus. The same is true of the thread's relationship to the mutex object, where the thread waits for the mutex object to be disposed using the Mutex.waitone () method, and if the mutex object it waits for is freed, it automatically owns the object until it calls Mutex.releasemutex () method to release the object, while other threads that want to acquire the mutex object are waiting. The following example uses a mutex object to synchronize four threads, the main thread waits for the end of four threads, and these four threads are associated with two mutex objects. It also uses the object of the AutoResetEvent class, which can be understood as a semaphore. It uses its signaled state to represent the end of a thread. The AutoResetEvent.Set () method sets it for an example of a program that has a signal state//Autoresetevent.reset () method that sets it to a non-signaled state Mutex class: Using System; Using System.Threading; Namespace Threadexample {public class Mutexsample {static mutex gM1; static mutex gM2; const int iters = +; static Aut Oresetevent Event1 = new AutoResetEvent (false); static AutoResetEvent Event2 = new AutoResetEvent (false); static AutoResetEvent Event3 = new AutoResetEvent (false); static AutoResetEvent Event4 = new AutoResetEvent (false); public static void Main (string[] args) {Console.WriteLine ("Mutex Sample"); Creates a mutex object and is named Mymutex gM1 = new Mutex (True, "Mymutex"); Creates a mutex object that is not named. gM2 = new Mutex (true); Console.WriteLine ("-Main owns GM1 and gM2"); Autoresetevent[] EVs = new AUTORESETEVENT[4]; Evs[0] = Event1; Define the AutoResetEvent object for the later thread t1,t2,t3,t4 evs[1] = Event2; EVS[2] = Event3; EVS[3] = Event4; 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 ();//Use the Mutex.waitall () method to wait for all objects in a mutex array to be released T2. Start ();//Use the Mutex.waitone () method to wait for the gM1 release T3. Start ();//Use the Mutex.waitany () method to wait for any object in a mutex array to be freed T4. Start ();//Use the Mutex.waitone () method to wait for the release of the GM2 Thread.Sleep (2000); Console.WriteLine ("-Main releases gM1"); Gm1.releasemutex (); Thread T2,t3 End condition satisfies thread.sleep (1000); Console.WriteLine ("-Main releases gM2"); Gm2.releasemutex (); Thread T1,t4 End condition satisfies//waits for all four threads to end WaitHandle.WaitAll (EVs); Console.WriteLine ("Mutex Sample"); ConsOle. ReadLine (); } public void T1start () {Console.WriteLine ("T1start started, Mutex.waitall (mutex[])"); mutex[] GMs = new mutex[2]; Gms[0] = gm1;//Creates a mutex array as a parameter of the Mutex.waitall () method gms[1] = gM2; Mutex.waitall (gMs);//wait for gM1 and gM2 to be released Thread.Sleep (2000); Console.WriteLine ("T1start Finished, Mutex.waitall (mutex[]) satisfied"); Event1.set (); Thread end, set Event1 to signaled state} public void T2start () {Console.WriteLine ("T2start started, Gm1.waitone ()"); Gm1.waitone (); Wait for the release of GM1 Console.WriteLine ("T2start Finished, Gm1.waitone () satisfied"); Event2.set ();//thread end, set Event2 to signaled state} public void T3start () {Console.WriteLine ("T3start started, Mutex.waitany (Mutex [])"); mutex[] GMs = new mutex[2]; Gms[0] = gm1;//Creates a mutex array as a parameter of the Mutex.waitany () method gms[1] = gM2; Mutex.waitany (gMs);//waits for any one of the Mutex objects in the array to be freed Console.WriteLine ("T3start Finished, Mutex.waitany (mutex[])"); Event3.set ();//thread end, set Event3 to signaled state} public void T4start () {Console.WriteLine ("T4start started, Gm2.waitone ()"); g M2. WaitOne ();//etcPending GM2 was released Console.WriteLine ("T4start Finished, Gm2.waitone ()"); Event4.set ();//thread end, set Event4 to signaled status}}} The output of the program: Mutex Sample-main owns gM1 and GM2 T1start started, Mutex.waitall (mutex[]) T2start started, Gm1.waitone () T3start started, Mutex.waitany (mutex[]) T4start started, Gm2.waitone ()-Main R Eleases gM1 T2start finished, Gm1.waitone () satisfied T3start finished, Mutex.waitany (mutex[])-Main releases gM2 T1Star T finished, Mutex.waitall (mutex[]) satisfied T4start finished, Gm2.waitone () Mutex Sample from the execution results can be clearly seen, thread T2, The operation of the T3 is conditional on the release of the GM1, and T4 executes after the gM2 is released, and T1 after GM1 and GM2 are released. The Main () function finally uses WaitHandle to wait for the signal of all AutoResetEvent objects, which represent the end of the corresponding thread.
C # multithreaded Learning (vi) Mutex objects