【问题标题】:Transferring ownership of .NET mutexes转移 .NET 互斥锁的所有权
【发布时间】:2011-10-17 18:51:53
【问题描述】:

我读过mutex 被线程拥有并且只能被拥有的线程使用。在this answer 中,该解决方案建议每个进程必须先取得互斥锁的所有权,然后再向另一个进程发出信号。我必须在这里承认我的愚蠢,我不知道如何将事件用于 IPC,因为它们在我阅读 MSDN 时没有出现,我喜欢唯一命名的 mutex 作为我的解决方案,但我不甚至知道如何在 WindowsService 和常规进程之间转移所有权。请帮忙。

我可以补充一下吗,Jon Skeet 的教程 here 告诉我,要在不同用户之间进行通信,就像我想的 LocalSystem 一样,需要在 mutex 名称前加上“Global\”前缀。我在 .NET 文档中找不到任何提及这一点,我想他是对的,我必须比我更关注 MSDN 系统之外。

【问题讨论】:

    标签: .net windows-services ipc mutex signals


    【解决方案1】:

    要获得现有 Mutex 的所有权,您可以使用静态方法 Mutex.OpenExisting() 和 MutexRights = TakeOwnership

    public static Mutex OpenExisting(
                                    string name,    
                                    MutexRights rights)
    
    • 权限参数必须包含 MutexRights.Synchronize 标志以允许线程在互斥体上等待,并包含 MutexRights.Modify 标志以允许它们调用ReleaseMutex() 方法。
    • OpenExisting 方法尝试打开现有的命名互斥体。如果系统互斥体不存在,该方法会抛出异常而不是创建系统对象。

    考虑到 OpenExisting() 可以抛出 UnauthorizedAccessException 异常,我建议使用以下构造函数创建一个新的 Mutex:

    public Mutex(
        bool initiallyOwned,
        string name,
        out bool createdNew
    )
    

    然后通过分析 createdNew 变量的值,您可以检查 mutext 是否已存在或是否已创建新的。

    【讨论】:

    • 几乎就像您在阅读 gmamaladze 的代码时阅读了我在答案中链接的页面(在我之前)!我不会厌倦再次听到它说的。让我感到困惑的是,第一个和第二个调用者都拥有同一个命名的互斥锁吗?因为两者都必须释放它才能锁定它?这似乎违反了我一次只锁定一个锁的目标。
    • @John:如果你知道这种技术,问题是什么?
    • 好吧,我无法重新输入 initiallyOwned 的智能感知参数描述,但我收集如果它是假的,或者命名的互斥锁已经存在,那么返回的互斥锁将是对已经存在的互斥锁的引用拥有。但这引出了一个问题,“如果我提供 false 并且它尚未拥有怎么办”,然后我将引用一个无主互斥体。我认为这是正确的。
    • @John :很抱歉造成混淆。关于您提供的链接 - 我还没有阅读它,看看 MSDN 中的 Mutex 类成员就足够了
    【解决方案2】:

    第一道工序:

    // Create a new Mutex. 
    // True means this thread/process has inital ownership
    Mutex mut = new Mutex(true, "some unique name");
    //Now do your job
    //Release ownership
    mut.ReleaseMutex();
    

    现在是第二个进程的代码。

    // Create an instance of mutex object with the same name
    // This means this thread/process has NOT inital ownership
    Mutex mut = Mutex.OpenExisting("some unique name");
    //Your thread will block until the first passes ownership
    mut.WaitOne();
    //Now you have it and can do your job
    

    【讨论】:

    • 很好的例子。他们对我来说不是第一和第二,而是平等的。在 VS 中,智能感知告诉我第一个参数应用 if 互斥锁是作为调用的结果创建的。因此,如果您所说的“第一个”排在第二位,它就不能假定它拥有所有权。我就是这么读的。
    【解决方案3】:

    This页面似乎已经相当完整地回答了我的问题,这里有一个味道:

    好吧,在mutex.WaitOne() 成功完成后,当前线程是互斥锁的所有者。然后在调用mutex.ReleaseMutex() 之后,线程不再拥有互斥锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      相关资源
      最近更新 更多