转移.NET互斥对象的所有权

3
我读到了有关mutex的文章,它是由线程拥有且仅能被拥有者线程使用。在这个答案中,解决方案建议每个进程在向另一个进程发出信号之前必须取得mutex的所有权。我必须承认我的愚蠢,在MSDN的阅读中我不知道如何使用IPC来代替mutex,我喜欢使用独特命名的mutex作为我的解决方案,但我甚至不知道如何在Windows服务和常规进程之间转移所有权。请帮帮我。
我还想补充一下,Jon Skeet的教程这里告诉我,要在不同用户之间进行通信(我假设LocalSystem是其中之一),需要在mutex名称前加上“Global\”。在.NET文档中我找不到这方面的提及,所以我觉得他是对的,我必须更多地查阅MSDN系统之外的资料。
3个回答

1

如果要获取已存在的 Mutex 的所有权,可以使用静态方法 Mutex.OpenExisting() 并设置 MutexRights = TakeOwnership。

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

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

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

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


几乎就像你在我读gmamaladze的代码时(之前),就已经阅读了我在答案中链接的页面!虽然我听到别人这么说不会厌烦。让我困惑的是,第一位和第二位用户呼叫者是否会拥有相同的命名互斥锁?也就是说,在任何一个呼叫者可以锁定它之前,两个呼叫者都必须释放它?这似乎违反了我的目标,即一次仅有一个锁。 - John
@John:如果你了解这个技巧,那还有什么问题呢? - sll
好的,我无法重新输入initiallyOwned的智能感知参数描述,但我了解如果它为false,或者命名的互斥体已经存在,则返回的互斥体将是一个已经拥有的引用。但这引出了一个问题,“如果我提供false而它尚未被拥有”,那么我将拥有一个未拥有的互斥体的引用。我认为是这样的。 - John
@John:抱歉让你感到困惑。关于你提供的链接,我没有阅读它,只需要查看MSDN中的Mutex类成员就足够了。 - sll

0

第一个进程:

// 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_。因此,如果您所称的'1st'在第二个位置,它不能假定它拥有所有权。这就是我理解的方式。 - John

0

这个页面似乎相当完整地回答了我的问题,以下是其中的一部分:

好的,在成功执行mutex.WaitOne()之后,当前线程就成为了互斥锁的所有者。然后,在调用mutex.ReleaseMutex()之后,该线程不再拥有该互斥锁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接