【问题标题】:Use mutex to lock an object使用互斥锁锁定对象
【发布时间】:2012-09-18 01:00:17
【问题描述】:

我有一个应用程序创建了一个需要锁定的对象,因为该对象创建了一个外部硬件设备对象(通过第三方 DLL),并且硬件设备对象只能创建一次。当启动此应用程序的多个实例时,只有第一个实例应该能够创建此 C# 对象。子序列实例应该看到对象已被锁定并且无法创建对象。我使用了互斥体,因为此对象创建发生在多个应用程序实例(多个进程)中。但是,该代码不会与互斥锁一起锁定。我是否正在运行多个实例,每个实例都创建自己的锁?

public sealed class MyObject
{
    private static MyObject _myObject;
    static ExtDeviceDriver devDrv;
    private readonly static Mutex mut = new Mutex();

    private MyObject()
    {
        mut.WaitOne();
        //Thread safe code here.
        devDrv = new ExtDeviceDriver();
    }

    ~MyObject()
    {
        mut.ReleaseMutex();
    }

    // object accessor
    public static MyObject GetMyObject
    {
        get
        {
            if (_myObject == null)
                _myObject = new MyObject();
            return _myObject;   
        }
    }
}

【问题讨论】:

标签: c# object mutex


【解决方案1】:

我猜你应该使用命名互斥锁 (See this article on MSDN)。

互斥体有两种类型:本地互斥体和命名系统互斥体。如果 您使用接受名称的构造函数创建一个 Mutex 对象,它 与该名称的操作系统对象相关联。命名 系统互斥锁在整个操作系统中都是可见的,并且可以 用于同步进程的活动。你可以创建 表示相同命名系统互斥体的多个互斥体对象,以及 您可以使用 OpenExisting 方法打开现有的命名系统 互斥体。

所以,尝试使用这个constructor 来创建一个命名的互斥锁。除了你应该检查它是否已经存在 Mutex.OpenExisting Method (考虑这篇文章中给出的例子;它告诉如何检查、创建、利用一个命名的互斥体)。

编辑

Mutex Class:

您可以使用 WaitHandle.WaitOne 方法来请求一个 互斥体。拥有互斥锁的线程可以请求相同的互斥锁 重复调用 WaitOne 而不阻止它的执行。然而 线程必须调用 ReleaseMutex 方法相同的次数才能 释放互斥锁的所有权。 Mutex 类强制执行线程 身份,因此只能由获取的线程释放互斥锁 它。

还有Mutex Constructor (Boolean, String),也就是说,必须将布尔参数设置为:

true 给调用线程 命名系统互斥锁的初始所有权(如果命名系统互斥锁) 由于此调用而创建;否则为假。

【讨论】:

  • 感谢您的指点。有没有办法在第二个应用程序实例中检查互斥锁是否已被采用并中止(不是旋转并使用 mutex.WaitOne() 等待),以便该实例可以继续执行其他操作?
  • @Kevin 看看WaitOne 方法重载列表:msdn.microsoft.com/en-us/library/…
  • @Kevin 即 WaitHandle.WaitOne 方法 (Int32) - 阻塞你的线程一段时间并返回false,如果它不能接受的话。跨度>
  • 我改代码使用:private Mutex mut = new Mutex(true, myMutex),调用mut.WaitOne(),最后调用mut.ReleaseMutex()退出临界区。第一个实例通过这个运行,它很好。第二个实例挂在 mut.WaitOne()。第一个实例必须通过上述代码再运行一次并通过它,因为它仍然具有互斥锁。然后第二个实例可以执行 pass mut.WaitOne()。似乎第一个实例直到第二次运行才释放互斥锁。为什么会这样?
  • 由于某些代码逻辑,第一个实例的第二次运行没有调用 mut.WaitOne()。这意味着第一个实例调用 mut.WaitOne() 一次(在第一次运行期间)但必须调用 mut.ReleaseMutex() 两次才能释放互斥锁。
猜你喜欢
  • 1970-01-01
  • 2021-03-24
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2017-02-23
  • 2010-09-16
相关资源
最近更新 更多