• 多线程学习笔记4 互斥体


    如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类。

    我们可以把Mutex看作一个出租车,乘客看作线程。乘客首先等车,然后上车,最后下车。当一个乘客在 车上时,其他乘客就只有等他下车以后才可以上车。而线程与Mutex对象的关系也正是如此,线程使用Mutex.WaitOne()方法等待Mutex对 象被释放,如果它等待的Mutex对象被释放了,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期 间,其他想要获取这个Mutex对象的线程都只有等待。

    下面这个例子使用了Mutex对象来同步四个线程,主线程等待四个线程的结束,而这四个线程的运行又是与两个Mutex对象相关联的。

    其中还用到AutoResetEvent类的对象,可以把它理解为一个信号灯。这里用它的有信号状态来表示一个线程的结束。
    // AutoResetEvent.Set()方法设置它为有信号状态

    // AutoResetEvent.Reset()方法设置它为无信号状态


    代码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;

    namespace ConsoleApplication1
    {
        
    public class MyMutex
        {
            Mutex m1;
            Mutex m2;

            AutoResetEvent aut1 
    = new AutoResetEvent(false);
            AutoResetEvent aut2 
    = new AutoResetEvent(false);
            AutoResetEvent aut3 
    = new AutoResetEvent(false);
            AutoResetEvent aut4 
    = new AutoResetEvent(false);

            
    public MyMutex()
            {
                m1 
    = new Mutex(true,"mutex1");
                m2 
    = new Mutex(true,"mutex2");
            }

            
    public void start1()
            {
                Console.WriteLine(
    "Thread1 start");
                m1.WaitOne();
                Console.WriteLine(
    "Thread1 end");
                aut1.Set();
                m1.ReleaseMutex();
            }
            
    public void start2()
            {
                Console.WriteLine(
    "Thread2 start");
                m2.WaitOne();
                Console.WriteLine(
    "Thread2 end");
                aut2.Set();
                m2.ReleaseMutex();
            }
            
    public void start3()
            {
                Console.WriteLine(
    "Thread3 start");
                Mutex[] list 
    = new Mutex[2];
                list[
    0= m1;
                list[
    1= m2;
                WaitHandle.WaitAll(list,Timeout.Infinite,
    true);
                Console.WriteLine(
    "Thread3 end");
                aut3.Set();
               
    foreach (Mutex m in list)
               {
                   m.ReleaseMutex();
               }
            }

            
    public void start4()
            {
                Console.WriteLine(
    "Thread4 start");
                Mutex[] list 
    = new Mutex[2];
                list[
    0= m1;
                list[
    1= m2;
                
    int k = Mutex.WaitAny(list);
                Console.WriteLine(
    "Thread4 end");
                list[k].ReleaseMutex();
            }


            
    public void Test()
            {
                Thread th1 
    = new Thread(new ThreadStart (start1));
                Thread th2 
    = new Thread(new ThreadStart (start2));
                Thread th3 
    = new Thread(new ThreadStart (start3));
                Thread th4 
    = new Thread(new ThreadStart (start4));

                th1.Start();
                th2.Start();
                th3.Start();
                th4.Start();

                AutoResetEvent[] autolist 
    = new AutoResetEvent[4];
                autolist[
    0= aut1;
                autolist[
    1= aut2;
                autolist[
    2= aut3;
                autolist[
    3= aut4;

                Console.WriteLine(
    "m2 ReleaseMutex");
                m2.ReleaseMutex();
                Console.WriteLine(
    "m1 ReleaseMutex ");
                m1.ReleaseMutex();

                WaitHandle.WaitAll(autolist);
                Console.WriteLine(
    "all Set");
                Console.ReadLine();
            }
        }
    }

    注意每次要释放互斥体 不然会引发AbandonedMutexException 异常

  • 相关阅读:
    【转】一个URL编码和解码的C++类
    ofstream的问题
    如何解决"应用程序无法启动,因为应用程序的并行配置不正确"问题(转载)
    最小生成树 prim & kruskal
    【2018百度之星资格赛】F 三原色图
    cout 按进制数出
    【2018百度之星资格赛】 A 问卷调查
    银河英雄传说
    读入读出挂!!
    关押罪犯
  • 原文地址:https://www.cnblogs.com/bobofsj11/p/1634270.html
Copyright © 2020-2023  润新知