您可以使用 System.Threading.Mutex 类,它有一个 OpenExisting 方法来打开一个命名的系统互斥锁。
这没有回答问题:
如何创建系统/多进程互斥体
要创建系统范围的互斥锁,请调用 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 来确保你拥有它。但是,你做了多少Releases?如果某个其他进程在您获得互斥锁时拥有它,那么只有您对WaitOne 的显式调用需要为Released。如果您对构造函数的调用导致您拥有互斥锁,并且您显式调用了WaitOne,则您将需要两个Releases。
我会把这些话写成代码:
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。