Вы можете использовать класс System.Threading.Mutex, который имеет метод OpenExisting для открытия именованного системного мьютекса.
Это не отвечает на вопрос:
Как создать системный / многопроцессорный Mutex
Чтобы создать общесистемный мьютекс, вызовите конструктор System.Threading.Mutex, который принимает строку в качестве аргумента.Это также известно как «именованный» мьютекс.Чтобы увидеть, существует ли он, я не могу найти более изящный метод, чем попытка 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.
}
Теперь, чтобы быть хорошим программистом, вам нужно, когда вы закончите программу, выпустить этоmutex
_mutey.ReleaseMutex();
или вы можете оставить его, и в этом случае он будет называться «покинутым» при выходе из вашего потока и позволит другому процессу его создать.
[EDIT]
В качестве дополнительного примечания к последнему предложению, описывающему мьютекс, который был оставлен, когда другой поток получает мьютекс, будет выдано исключение 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);
Я думаю, что хитрость в том, что кажется, чтоу вас есть вариант, которого у вас на самом деле нет (выглядит для меня как недостаток дизайна).Иногда вы не можете определить, владеете ли вы мьютексом, если отправите true
для requestInitialOwnership
.Если вы передаете true
и кажется, что ваш вызов создал мьютекс, то, очевидно, вы им владеете (подтверждается документацией).Если вы передаете true
, и ваш вызов не создал мьютекс, все, что вы знаете, это то, что мьютекс уже создан, вы не знаете, владеет ли мьютекс каким-либо другим процессом или потоком, который, возможно, создал мьютекс.Итак, вам нужно WaitOne
, чтобы убедиться, что оно у вас есть.Но тогда, сколько Release
с вы делаете?Если какой-то другой процесс владел мьютексом, когда вы его получили, то только ваш явный вызов WaitOne
должен быть Release
d.Если ваш вызов конструктора заставил вас владеть мьютексом, и вы вызвали WaitOne
явно, вам понадобятся два Release
s.
Я вставлю эти слова в код:
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
.