NET multi-threaded programming (5): Case learning multi-threaded
In the previous multi-threaded programming series, we understand the basic knowledge that multi-threaded programming must be mastered in .NET, it may be very vague after reading the article, and it is still very vague. Going to do, the reason may be too much in theory, and there is not much practical reference example, causing a lot of harvest. Therefore, in the next article, I will give several examples of typical multi-threaded programming, let everyone have a clearer understanding.
Case 1 - no synchronization
In our first example, there are two types of threads, two are reading threads, one is written thread, two threads are run in parallel and need to access the same shared resource. The read thread is started before the write thread is used to set the value of the shared variable. I use thread.sleep to complete these work. The extract code is as follows:
Thread T0 = New Thread (New ThreadStart (WriteTHRead);
Thread T1 = New Thread (New ThreadStart (ReadThread10);
Thread T2 = New Thread (New ThreadStart (ReadThread20));
T0.Insbackground = true;
T1.Background = true;
T2.Background = Trued;
T0.START ();
T1.Start ();
T2.Start ();
As seen, start two write threads immediately after the reading thread starts. The following code is the code executed by two read threads and write threads.
Public void whitthread ()
{
Thread.sleep (1000);
m_x = 3;
}
Public void readthread10 ()
{
INT A = 10;
For (int y = 0; y <5; y )
{
String s = "readthread10";
s = s "# Multiplier =";
S = S Convert.toString (a) "#";
S = s a * m_x;
ListBox1.Items.Add (s);
Thread.sleep (1000);
}
}
Public void readthread20 ()
{
INT A = 20;
For (int y = 0; y <5; y )
{
String s = "readthread20";
s = s "# Multiplier =";
S = S Convert.toString (a) "#";
S = s a * m_x;
ListBox1.Items.Add (s);
Thread.sleep (1000);
}
}
The result of the final run is as follows:
Through the above operation results, we can clearly see that the results we expect, the two results started, the reading thread is running before writing the thread, this is what we try to avoid happening.
Case 2 - Synchronization [One WritThread - Many Readthreads]
Below I will use ManualRetevent to solve the problems encountered above to reach the synchronization of the line, the only difference is how we use secure before starting the reading thread and writing threads.
Thread T0 = New Thread (New ThreadStart (New Threadstart); Thread T1 = New Thread (New ThreadStart (SafeReadThread10);
Thread T2 = New Thread (New ThreadStart (SafeReadthread20);
T0.Insbackground = true;
T1.Background = true;
T2.Background = Trued;
T0.START ();
T1.Start ();
T2.Start ();
Add a ManualReveTevent:
M_mre = new manualReveTevent (false);
Take a look at the code of SafeWritThread:
Public void saFewritthread ()
{
m_mre.reset ();
Writethread ();
m_mre.set ();
}
RESET Set the status of ManualRetevent to non-signal, which means that the event has not happened. Then we call the Writethread method, which can actually skip the RESET because we set their status as non-signal thelays in the constructor of ManualRetevent. Once the Writethread thread returns, call the SET method to set the status of ManualRetevent to signal.
Let's take another two SafeReadthread methods:
Public void safereadthread10 ()
{
m_mre.waitone ();
Readthread10 ();
}
Public void safereadthread20 ()
{
m_mre.waitone ();
Readthread20 ();
}
The waitone method will block the current thread until the status of ManualRetevent is set to Signaled. Here, both of our two reading threads will block the SAFEWRITETHREAD to complete the task after calling the SET method. This way we ensure that the two read threads will only be implemented after the write thread completes access to the shared resource. The following is the result of the run:
Case 3 - Synchronization [Many Writethreads - MANY Readthreads]
Below we will simulate more complicated situations. In the following program, there are multiple write threads and reading threads. The reading thread can only access the shared resource after all the write threads have completed the task. In practical cases, the reading thread may be parallel to run, but for the sake of simplicity, I have a certain order in the write thread running, and the second write thread is only started after the previous write thread is completed.
Here, I added an array of ManualResetEvent objects and ManualResetEvent.
Public ManualReveTevent M_Mreb;
Public ManualReveTevent [] M_MRE_ARRAY;
Add initialization code:
m_mreb = new manualRetevent (false);
M_mre_ARRAY = New ManualRetevent [2];
M_mre_Array [0] = m_mre;
M_mre_Array [1] = m_mreb;
Start four threads:
Thread T0 = New Thread (New ThreadStart (SafeWritTHREAD);
Thread T0B = New Thread (New ThreadStart (SafeWritTHReadb);
Thread T1 = New Thread (New Threadstart (SafereadThread10b); Thread T2 = New Thread (New ThreadStart (SafeReadThread20B);
T0.Insbackground = true;
T0B.isbackground = true;
T1.Background = true;
T2.Background = Trued;
T0.START ();
T0B.Start ();
T1.Start ();
T2.Start ();
There are two StartThreads and two Writthreads, let's take a look at their execution:
Public void saFewritthread ()
{
m_mre.reset ();
Writethread ();
m_mre.set ();
}
Public void saFewritThreadb ()
{
m_mreb.reset ();
m_mre.waitone ();
Thread.sleep (1000);
m_x = 3;
m_mreb.set ();
}
I used another event object for the second Writethread, and the first thread was waiting to work.
Public void safereadthread10b ()
{
Waithandle.waitall (M_MRE_ARRAY);
Readthread10 ();
}
Public void safereadthread20b ()
{
Waithandle.waitall (M_MRE_ARRAY);
Readthread20 ();
}
Here, use a Waitall method, he is a static method of the WaitHandle base class to ManualRetevent, which is the manualResetEvent array of the previously defined in front. He blocked the current thread until the MANUALRESETEVENT object setting status in the array array is SIGNALED, and it is to wait for them to complete their tasks.