Thread Synchronization-Wait For All threads to finish execution

Source: Internet
Author: User

Thread Synchronization is often encountered in multi-threaded programs:

Scenario 1

After the main thread starts multiple sub-threads, the main thread needs to wait until all the sub-threads have completed the execution before the main thread can further execute down.

C # provides the ManualResetEvent class to facilitate thread synchronization.

ManualResetEvent.WaitAll(New WaitHandle [] {});

 

The WaitAll static method can block the execution of the current thread until each thread in WaitHandle [] sends a signal for blocking and unblocking.

 

You can pass a Boolean value to the constructor to control the initial status of ManualResetEvent. If the initial status is terminated, the value is true; otherwise, the value is false.

 

ManualResetEvent.Set() The method sends a blocking termination signal. When other threads receive a signal from the thread to block the termination, the program continues to run.

 

 

Scenario: the main thread needs to sum the data produced by sub-thread 1 with the data generated by sub-thread 2. The main thread starts thread 1 to wait for data generation 1 and start thread 2 to wait for data generation 2. Only when

After data 1 and 2 are generated, the main thread can sum the data.

 

The Code is as follows:

Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; using System. diagnostics; namespace ThreadStudy. hbb0b0 {/// <summary> /// example shows how the main thread continues to execute after all the auxiliary threads are executed. /// The main thread starts the auxiliary thread 1 to generate the addition 1, and starts the auxiliary thread 2 to generate the addition 2 // after the main thread waits for the addition generated by the auxiliary thread 1 and the auxiliary thread 2, add the number // and output the result. /// </Summary> class Program {delegate int operateNumber (int a, int B); delegate int generateNumber (int a); static int result1; static int result2; static void Main (string [] args) {// ManualResetEvent m1 = new ManualResetEvent (false ); // ManualResetEvent m2 = new ManualResetEvent (false); generateNumber g1 = ThreadTool. generateNumber; generateNumber g2 = ThreadTool. generateNumber; AsyncCallback g1_callback = delegate (IAsyncResult ar) {result1 = g1.EndInvoke (ar); Console. writeLine ("thread id: {0} current number: {1} block stop", Thread. currentThread. managedThreadId, result1); // The m1.Set () ;}; AsyncCallback g2_callback = delegate (IAsyncResult ar) {result2 = g2.EndInvoke (ar); Console. writeLine ("thread id: {0} current number: {1} block stop", Thread. currentThread. managedThreadId, result2); // The m2.Set () ;}; Console. writeLine ("generate numbers:"); // auxiliary thread 1 starts g1.BeginInvoke (10, g1_callback, null); // auxiliary thread 2 starts g2.BeginInvoke (100, g2_callback, null ); // The main thread waits for all the auxiliary threads to return to ManualResetEvent. waitAll (new WaitHandle [] {m1, m2}); int sum = ThreadTool. sum (result1, result2); Console. writeLine ("{0} + {1} = {2}", result1, result2, sum); Console. read ();}} public class ThreadTool {// <summary> // generate a number /// </summary> /// <param name = "maxNum"> </param> /// <returns> </returns> static public int GenerateNumber (int maxNum) {Console. writeLine ("thread Id: {0} generate number", Thread. currentThread. managedThreadId); Thread. sleep (5000); int result = new Random (int) DateTime. now. ticks ). next (maxNum); return result ;} /// <summary> /// accumulate result /// </summary> /// <param name = "a"> </param> /// <param name = "B"> </param> // <returns> </returns> static public int sum (int, int B) {Console. writeLine ("thread Id: {0} gernerate number", Thread. currentThread. managedThreadId); Thread. sleep (6000); return a + B ;}}}

 

 

 

Scenario 2:

The main thread starts thread 1 and sub-thread 2. As long as sub-thread 1 or sub-thread 2 completes execution, the main thread can continue execution.

 

The Code is as follows:

Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; namespace ThreadWaitOne {class ThreadStartParameterInfo {// <summary> // thread signal // </summary> public ManualResetEvent m_mr; /// <summary> /// thread wait time /// </summary> public int m_waitTicks; public ThreadStartParameterInfo (ManualResetEvent mr, int waitTicks) {m_mr = mr; m_waitTicks = waitTicks;} public class ThreadTool {private object m_SyncObject = new object (); private int currentThreadId =-1; public void Main () {for (int I = 0; I <5; I ++) {ManualResetEvent mr1 = new ManualResetEvent (false); ManualResetEvent mr2 = new ManualResetEvent (false); ManualResetEvent mr3 = new ManualResetEvent (false ); parameterizedThreadStart pts1 = new ParameterizedThreadStart (this. generateNumber); ParameterizedThreadStart pts2 = new ParameterizedThreadStart (this. generateNumber); ParameterizedThreadStart pts3 = new ParameterizedThreadStart (this. generateNumber); Thread ts1 = new Thread (pts1); Thread ts2 = new Thread (pts1); Thread ts3 = new Thread (pts1); ts1.Start (new ThreadStartParameterInfo (mr1, 3010); ts2.Start (new ThreadStartParameterInfo (mr2, 3020); ts3.Start (new ThreadStartParameterInfo (mr3, 3030); // The main thread waits for any thread, after any thread sends a blocking completion signal, the main thread can continue to execute ManualResetEvent. waitAny (new WaitHandle [] {mr1, mr2, mr3}); Console. writeLine ("Main Thread: The fast thread: {0}", currentThreadId) ;}} public void GenerateNumber (object resetEvent) {ThreadStartParameterInfo threadInfo = resetEvent as ThreadStartParameterInfo; // ManualResetEvent mr = resetEvent as ManualResetEvent; Console. writeLine ("thread Id: {0} wait: {1} generate number start :..... ", Thread. currentThread. managedThreadId, threadInfo. m_waitTicks); Thread. sleep (threadInfo. m_waitTicks); int radomNumber = new Random (int) DateTime. now. ticks ). next (1000); lock (m_SyncObject) {currentThreadId = Thread. currentThread. managedThreadId;} Console. writeLine ("thread Id: {0} generate number: {1}", Thread. currentThread. managedThreadId, radomNumber); threadInfo. m_mr.Set ();}}}

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.