互斥锁

http://zwkufo.blog.163.com/blog/static/258825120104297724292/

互斥锁(Mutex)

互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。

互斥锁可适用于一个共享资源每次只能被一个线程访问的情况

 函数:

//创建一个处于未获取状态的互斥锁

Public Mutex();

//如果owned为true,互斥锁的初始状态就是被主线程所获取,否则处于未获取状态

 Public Mutex(bool owned);

 如果要获取一个互斥锁。应调用互斥锁上的WaitOne()方法,该方法继承于Thread.WaitHandle类

它处于等到状态直至所调用互斥锁可以被获取,因此该方法将组织住主调线程直到指定的互斥锁可用,如果不需要拥有互斥锁,用ReleaseMutex方法释放,从而使互斥锁可以被另外一个线程所获取。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace MyTTCon
{
    class shareRes
    {
        public static int count = 0;
        public static Mutex mutex = new Mutex();
    }

    class IncThread
    {
        int number;
        public Thread thrd;
        public IncThread(string name, int n)
        {
            thrd = new Thread(this.run);
            number = n;
            thrd.Name = name;
            thrd.Start();
        }
        void run()
        {
            Console.WriteLine(thrd.Name + "正在等待 the mutex");
            //申请
            shareRes.mutex.WaitOne();
            Console.WriteLine(thrd.Name + "申请到 the mutex");
            do
            {
                Thread.Sleep(1000);
                shareRes.count++;
                Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count);
                number--;
            } while (number > 0);
            Console.WriteLine(thrd.Name + "释放 the nmutex");
            //  释放
            shareRes.mutex.ReleaseMutex();
        }
    }
    class DecThread
    {
        int number;
        public Thread thrd;
        public DecThread(string name, int n)
        {
            thrd = new Thread(this.run);
            number = n;
            thrd.Name = name;
            thrd.Start();
        }
        void run()
        {
            Console.WriteLine(thrd.Name + "正在等待 the mutex");
            //申请
            shareRes.mutex.WaitOne();
            Console.WriteLine(thrd.Name + "申请到 the mutex");
            do
            {
                Thread.Sleep(1000);
                shareRes.count--;
                Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count);
                number--;
            } while (number > 0);
            Console.WriteLine(thrd.Name + "释放 the nmutex");
            //  释放
            shareRes.mutex.ReleaseMutex();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IncThread mthrd1 = new IncThread("IncThread thread ", 5);
            DecThread mthrd2 = new DecThread("DecThread thread ", 5);
            mthrd1.thrd.Join();
            mthrd2.thrd.Join();
        }
    }
}

System.Threading.Mutex在概念上和System.Threading.Monitor几乎完全一致,只是lock关键字用的不是它,而且它旨在进程间的同步。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace myConApp
{
    class Test
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            bool flag = false;
            System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Test", out flag);
            //第一个参数:true--给调用线程赋予互斥体的初始所属权
            //第一个参数:互斥体的名称
            //第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true
            if (flag)
            {
                Console.Write("Running");
            }
            else
            {
                Console.Write("Another is Running");
                System.Threading.Thread.Sleep(5000);//线程挂起5秒钟
                Environment.Exit(1);//退出程序
            }
            Console.ReadLine();

        }
    }
}

 运行以上代码生成的应用程序第一个实例,会得到结果

Running

 保持第一个运行状态,运行第二个实例,得到结果

Another  is  Running

 以上代码中创建了一个mutex,从其参数的解释中得知,第一个调用线程将得到互斥体的初始所属权,如果不释放的话,其他的线程得不到互斥体所有权

 下面看一段代码(出自 http://space.itpub.net/12639172/viewspace-448867 ),稍有改动


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MonitorLockMutex
{
    class Program
    {

        Thread thread1 = null;
        Thread thread2 = null;
        Mutex mutex = null;

        static void Main(string[] args)
        {
            Program p = new Program();
            p.RunThread();
            Console.ReadLine();
        }
        public Program()
        {
            mutex = new Mutex();
            thread1 = new Thread(new ThreadStart(thread1Func));
            thread2 = new Thread(new ThreadStart(thread2Func));
        }
        public void RunThread()
        {
            thread1.Start();
            thread2.Start();
        }
        private void thread1Func()
        {
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread1 have run " + count.ToString() + " times");
                //暂停500ms
                Thread.Sleep(500);
            }
        }
        private void thread2Func()
        {
            for (int count = 0; count < 10; count++)
            {      
                TestFunc("Thread2 have run " + count.ToString() + " times");
                //暂停1500ms
                Thread.Sleep(1500);
            } 
        }
        private void TestFunc(string str)
        {
           
                Console.WriteLine("{0} {1}", str, System.DateTime.Now.Millisecond);
            
        }
    }
}

 两个线程基本上是按照各自的时间间隔+TestFunc的执行时间对TestFunc函数进行读取

 将公共调用的函数加锁


 private void TestFunc(string str)
        {
            lock (this)
            {
                Console.WriteLine("{0} {1}", str, System.DateTime.Now.Millisecond);
            }            
        }

 再次运行查看结果,好像没什么区别?

 加入mutex


private void thread1Func()
        {
            mutex.WaitOne();
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread1 have run " + count.ToString() + " times");
                //暂停500ms
                Thread.Sleep(500);
            }
            mutex.ReleaseMutex();
        }
        private void thread2Func()
        {
            mutex.WaitOne();
            for (int count = 0; count < 10; count++)
            {      
                TestFunc("Thread2 have run " + count.ToString() + " times");
                //暂停1500ms
                Thread.Sleep(1500);
            }
            mutex.ReleaseMutex();
        }

 再次运行查看结果。

 C多线程 - Mutex - 乂乂 - 一个人,一支烟  ·~~

想到了什么?thread1Func() 或者thread2Func()中的全部执行完毕,之后释放互斥体,然后剩下的那个才可以访问。

 再改动一次


 private void thread1Func()
        {          
            for (int count = 0; count < 10; count++)
            {
                lock (this)
                {
                    mutex.WaitOne();
                    TestFunc("Thread1 have run " + count.ToString() + " times");
                    //暂停500ms
                    Thread.Sleep(500);
                    mutex.ReleaseMutex();
                }
            }           
        }
        private void thread2Func()
        {           
            for (int count = 0; count < 10; count++)
            {
                lock (this)
                {
                    mutex.WaitOne();
                    TestFunc("Thread2 have run " + count.ToString() + " times");
                    //暂停1500ms
                    Thread.Sleep(1500);
                    mutex.ReleaseMutex();
                }
            }           
        }

 看效果……

C多线程 - Mutex - 乂乂 - 一个人,一支烟  ·~~ 

 轮换执行……

【from  hsrzyn http://www.cnblogs.com/hsrzyn/articles/1588140.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值