Mutex的wait和release必须成对出现,如果在一个类中调用mutex的wait方法没有release,则会报AbandonedMutexException错误
Mutex对象等待互斥对象的方法有:Mutex.WaitAll、WaitOne、Mutex.WaitAny
每个对象的release方法略有区别
方法如下
* (1)、WaitOne()
Mutex gM1=new Mutex();
gM1.WaitOne();//等待gM1的释放
gM1的释放为:
gM1.ReleaseMutex();
(2)、WaitAll()
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
gMs[1] = gM2;
Mutex.WaitAll(gMs); //等待gM1和gM2的释放
for (int i = 0; i < gMs.Length; i++)
{
gMs[0].ReleaseMutex();
}
(3)、WaitAny()
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
gMs[1] = gM2;
int index = Mutex.WaitAny(gMs); //等待数组中任意一个Mutex对象被释放
Mutex对象等待互斥对象的方法有:Mutex.WaitAll、WaitOne、Mutex.WaitAny
每个对象的release方法略有区别
方法如下
* (1)、WaitOne()
Mutex gM1=new Mutex();
gM1.WaitOne();//等待gM1的释放
gM1的释放为:
gM1.ReleaseMutex();
(2)、WaitAll()
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
gMs[1] = gM2;
Mutex.WaitAll(gMs); //等待gM1和gM2的释放
for (int i = 0; i < gMs.Length; i++)
{
gMs[0].ReleaseMutex();
}
(3)、WaitAny()
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
gMs[1] = gM2;
int index = Mutex.WaitAny(gMs); //等待数组中任意一个Mutex对象被释放
gMs[index].ReleaseMutex();
/* 下面的代码使用了 AutoResetEvent和mutex
* T2和T3方法完成触发 mutex1释放,T1和T4完成触发mutex2释放。所有的AutoResetEvent完成,触发WaitHandle.WaitAll(evs);*/
class Program
{
static Mutex gM1;
static Mutex gM2;
static AutoResetEvent event1 = new AutoResetEvent(false);
static AutoResetEvent event2 = new AutoResetEvent(false);
static AutoResetEvent event3 = new AutoResetEvent(false);
static AutoResetEvent event4 = new AutoResetEvent(false);
static void Main(string[] args)
{
gM1 = new Mutex(true);
// 如果是true则表示拥有互斥体的所有权,false表示不拥有互斥体的所有权。
gM2 = new Mutex(true);
AutoResetEvent[] evs = new AutoResetEvent[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
Program tm = new Program();
Thread thread1 = new Thread(new ThreadStart(tm.t1Start));
Thread thread2 = new Thread(new ThreadStart(tm.t2Start));
Thread thread3 = new Thread(new ThreadStart(tm.t3Start));
Thread thread4 = new Thread(new ThreadStart(tm.t4Start));
thread1.Start(); // Does Mutex.WaitAll(Mutex[] of gM1 and gM2)
thread2.Start(); // Does Mutex.WaitOne(Mutex gM1)
thread3.Start(); // Does Mutex.WaitAny(Mutex[] of gM1 and gM2)
thread4.Start(); // Does 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
// Waiting until all four threads signal that they are done.
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; // Create and load an array of Mutex for WaitAll call
gMs[1] = gM2;
Mutex.WaitAll(gMs); // Waits until both gM1 and gM2 are released
Thread.Sleep(2000);
Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied");
event1.Set(); // AutoResetEvent.Set() flagging method is done
gM1.ReleaseMutex();
gM2.ReleaseMutex();
}
public void t2Start()
{
Console.WriteLine("t2Start started, gM1.WaitOne( )");
gM1.WaitOne(); // Waits until Mutex gM1 is released ---errors is here---
Console.WriteLine("t2Start finished, gM1.WaitOne( ) satisfied");
gM1.ReleaseMutex();
event2.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t3Start()
{
Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call
gMs[1] = gM2;
int result = Mutex.WaitAny(gMs); // Waits until either Mutex is released
gMs[result].ReleaseMutex();
Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");
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
gM2.ReleaseMutex();
}
}