码迷,mamicode.com
首页 > Windows程序 > 详细

关于C#的互斥

时间:2015-12-04 17:49:57      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

以下内容有错误请指正,为个人理解和经验。

c#提供三种互斥Monitor类、Lock和Mutex类,他们的区别和使用方法如下:

一、Lock类

名叫“临界区”,为Monitor的封装版,用于多线程,对单线程无用,即支持在同一个线程内多次调用lock锁定同一个目标。

用法

            lock (this) { 
                //执行代码
            }

效果为在多个线程内调用同一个函数时,函数内部使用锁定方法,可以让线程进行“排队”等候,直到lock结束为止,然后其他函数才能排队进入下一个执行代码。

等待为无限等待,直到占用被释放,否则线程一直阻塞。

注意事项:不建议锁定Public对象(含this,typeof(Type),"字符串"),别和上面的例子一样使用this,强烈不推荐,因为如果lock了自己的同时,可能还存在外部有锁定该对象的可能,造成同一个对象被多个函数内部锁定,可能影响效率。建议如下使用

        private object obj = new object();
        public void Test()
        {
            lock (obj)
            {
                //执行代码
            }
        }

二、Monitor类

和Lock效果一致,使用方法不同

        private object obj = new object();
        public void Test()
        {
            if (System.Threading.Monitor.TryEnter(obj, 1000))//排队等待1秒
            {
                //执行代码
                System.Threading.Monitor.Exit(obj);//退出
            }
            else
            {
                //排队等不到,就不等了
            }
        }

可以看出,区别是增加了时间,也就是如果排队不耐烦了,可以不等了,而离开队伍,对此,System.Threading.Monitor还提供多个函数使用

Enter尝试获取一个对象,同时第二个可选参数返回是否获取成功

TryEnter尝试获取一个对象,并在第二个可选参数上设置尝试的等待时间

Wait释放获得的对象,并在第二个可选参数时间后再次尝试获取该对象(即排队到自己后,自己办理中途整理资料停一会,让给其他人办,然后继续办理)

Exit释放获得的对象,和Wait类似,但不阻塞当前线程,也不尝试再次获取该对象

Pulse(),PulseAll()向一个或多个等待线程发送信号,表示自己即将释放对象,请大家做好准备,一般在Exit或者Wait前调用,可提高性能。

三、Mutex类

名字叫互斥锁(互斥体,互斥量),可用于多线程,功能类似Monitor,但它主要的用途不是用于多线程,而是用于进程。

特点仍然是拥有执行权的线程可以多次拥有,但也必须多次释放。

使用方法

        private static System.Threading.Mutex mutex = null;//设置为static成员,是为了在整个程序生命周期内都持有Mutex
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            bool firstInstance;
            mutex = new System.Threading.Mutex(true, "name", out firstInstance);
            if (!firstInstance) {
                MessageBox.Show("存在");
                return;
            }
        }

主要为2个函数ReleaseMutex和WaitOne,前者是释放,后者是等待释放的信号。

上面的代码的构造函数的第一个参数就是是否立即获取,第二个参数是互斥体的名称,注意是全局的,可以不填为匿名,但如果填了就不能再创建同名的互斥体(包括不同的软件,所以建议使用程序名)。

 

关于C#的互斥

标签:

原文地址:http://www.cnblogs.com/21tcy/p/5019766.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!