- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
如何创建系统/多进程互斥体来协调使用相同非托管资源的多个进程。
背景: 我写了一个使用文件打印机的程序,一次只能由一个进程使用。如果我想在计算机上运行的多个程序上使用它,我需要一种跨系统同步的方法。
最佳答案
You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
这没有回答问题:
How can I create a system/multiprocess Mutex
要创建系统范围的互斥量,请调用以字符串作为参数的 System.Threading.Mutex 构造函数。这也称为“命名”互斥体。要查看它是否存在,我似乎找不到比 try catch 更优雅的方法了:
System.Threading.Mutex _mutey = null;
try
{
_mutey = System.Threading.Mutex.OpenExisting("mutex_name");
//we got Mutey and can try to obtain a lock by waitone
_mutey.WaitOne();
}
catch
{
//the specified mutex doesn't exist, we should create it
_mutey = new System.Threading.Mutex("mutex_name"); //these names need to match.
}
现在,要成为一名优秀的程序员,您需要在程序结束时释放这个互斥量
_mutey.ReleaseMutex();
或者,您可以保留它,在这种情况下,当您的线程退出时,它将被称为“已放弃”,并允许另一个进程创建它。
[编辑]
作为描述被遗弃的互斥锁的最后一句话的旁注,当另一个线程获取互斥锁时,将抛出异常 System.Threading.AbandonedMutexException
告诉他它在被遗弃的状态。
[编辑两个]
我不确定为什么我在几年前就这样回答了这个问题;有(并且曾经)有一个构造函数重载,它在检查现有互斥量方面要好得多。事实上,我给出的代码似乎存在竞争条件! (你们都因为没有纠正我而感到羞耻!:-P)
这是竞争条件:假设有两个进程,它们都试图同时打开现有的互斥量,并且都到达代码的 catch 部分。然后,其中一个进程创建互斥量并从此过上幸福的生活。然而,另一个进程试图创建互斥量,但这次它已经创建了!这种互斥量的检查/创建需要是原子的。
http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx
所以...
var requestInitialOwnership = false;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
我认为这里的诀窍在于,您似乎有一个实际上没有的选项(对我来说看起来像是设计缺陷)。如果您为 requestInitialOwnership
发送 true
,有时您无法判断您是否拥有互斥量。如果您传递 true
并且看起来您的调用创建了互斥量,那么显然您拥有它(由文档确认)。如果您传递 true
并且您的调用没有创建互斥量,您所知道的就是互斥量已经创建,您不知道是否有其他进程或线程可能创建了互斥量当前拥有互斥体。因此,您必须 WaitOne
以确保您拥有它。但是,您做了多少 Release
?如果在您获得互斥量时其他进程拥有它,则只有您对 WaitOne
的显式调用需要被 Release
d。如果您对构造函数的调用导致您拥有互斥量,并且您显式调用了 WaitOne
,则您将需要两个 Release
。
我会把这些话写成代码:
var requestInitialOwnership = true; /*This appears to be a mistake.*/
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
if ( !mutexWasCreated )
{
bool calledWaitOne = false;
if ( ! iOwnMutex(m) ) /*I don't know of a method like this*/
{
calledWaitOne = true;
m.WaitOne();
}
doWorkWhileHoldingMutex();
m.Release();
if ( calledWaitOne )
{
m.Release();
}
}
因为我没有找到测试你当前是否拥有互斥量的方法,我强烈建议你将 false
传递给构造函数,这样你就知道你不拥有互斥量,并且您知道要调用多少次 Release
。
关于c# - 如何在 C# 中创建系统互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2186747/
我是一名优秀的程序员,十分优秀!