利用設定ManualResetEvent的信號來控制多執行緒,等到多執行緒都同時完成某件事之後,才回到主要執行緒進行後續程式流程。這就是所謂的多執行緒同步
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ResetEventTest
{
class Program
{
/*
* reference:https://gmpg.org/xfn/11
*/
private static ManualResetEvent mre_1 = new ManualResetEvent(false);
private static ManualResetEvent mre_2 = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("\nStart 10 named threads that block on a ManualResetEvent:\n");
for (int i = 0; i <= 10; i++)
{
Thread t = new Thread(ThreadProc_1);
t.Name = /*"Thread_" +*/ i.ToString();
t.Start(); //開始線程
}
Thread.Sleep(10000);
Console.WriteLine("\n Waiting for 10Seconds..... \n");
for (int i = 11; i <= 13; i++)
{
Thread t = new Thread(ThreadProc_2);
t.Name = /*"Thread_" +*/ i.ToString();
t.Start(); //開始線程
}
Thread.Sleep(120000);
Console.WriteLine("\n Waiting for 120Seconds..... \n");
}
private static void ThreadProc_1()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine("Thread " + name + " starts and calls mre.WaitOne()");
if (Convert.ToInt16(name) % 2 == 0)
{
mre_2.WaitOne();//執行緒2.4.6.8.10綁定mre_2,並阻塞MRE
}
else
{
mre_1.Set();//執行緒1.3.5.7.9綁定mre_1,開啟mre_1綠燈
}
Console.WriteLine("Thread " + name + " end mre.WaitOne()");
}
private static void ThreadProc_2()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine("Thread " + name + " starts and calls mre.WaitOne()");
if (Convert.ToInt16(name) % 2 == 0)
{
mre_2.Set();//執行緒12綁定mre_2,開啟mre_2綠燈。執行緒2.4.6.8.10繼續執行line55
}
else
{
mre_1.Set();//執行緒11.13綁定mre_1,開啟mre_1綠燈
}
Console.WriteLine("Thread " + name + " end mre.WaitOne()");
}
}
}
執行結果:
第一個迴圈new出10個執行緒,執行緒1.3.5.7.9從MRE_1取得控制信號。執行緒2.4.6.8.10從MRE_2取得控制信號。
MRE_1信號為Set(),所以執行緒1.3.5.7.9動作不會被中止
成功執行Console.WriteLine("Thread " + name + " end ThreadProc_1 mre.WaitOne()");
因為MRE_2信號為WaitOne(),執行緒會被阻塞,所以執行緒2.4.6.8.10動作被中止
無法執行Console.WriteLine("Thread " + name + " end ThreadProc_1 mre.WaitOne()");
第二個迴圈new出3個執行緒,執行緒11.13從MRE_1取得控制信號。執行緒12從MRE_2取得控制信號。
MRE_1信號狀態為Set(),所以執行緒11.13動作不會被中止
成功執行Console.WriteLine("Thread " + name + " end ThreadProc_2 mre.WaitOne()");
MRE_2信號狀態為Set(),所以執行緒12動作不會被中止
成功執行Console.WriteLine("Thread " + name + " end ThreadProc_2 mre.WaitOne()");
由於MRE_2的信號由WaitOne()變更為Set(),故原本在ThreadProc_1被中止動作的執行緒2.4.6.8.10解除中止
繼續往下執行Console.WriteLine("Thread " + name + " end ThreadProc_1 mre.WaitOne()");