Какая польза от мьютекса, если вы не можете назвать его?

Мне трудно понять, чем хорош мьютекс, не называя его. В частности, я хочу сделать свое приложение Windows Mobile 6.5 единственным экземпляром.

На этом сайте есть несколько вопросов и ответов о том, как это сделать, и лучшие из них, похоже, используют именованные мьютексы.

К сожалению, CTORS для мьютексов в компактной среде не принимают строка - можно только создать мьютекс.

Что хорошего в мьютексе, если у него нет связанного идентификатора?

Я что-то упускаю?

Как использовать мьютекс для защиты ресурса в нескольких приложениях, если я не могу назвать их?


person Tim    schedule 06.10.2011    source источник
comment
Да, есть куча простых вещей, которые должны быть в .NET CF, но их нет. Вам нужно только просмотреть документы MSDN для всех классов и методов без глупого маленького значка устройства. Думаю, мы все должны поблагодарить Microsoft за то, что они сделали больше работы и сохранили наши рабочие места в безопасности.   -  person Damon8or    schedule 07.10.2011
comment
Это связанный с этим вопрос: stackoverflow.com/questions/867050/   -  person ctacke    schedule 07.10.2011


Ответы (2)


В самом компакте фреймворка нет.

Какая польза от мьютекса, если вы не можете назвать его?

Безымянный мьютекс называется локальным мьютексом. Вы по-прежнему можете использовать его для синхронизации между различными потоками в одном и том же процессе. Монитор, подобный ключевому слову lock, не имеет такой же функциональности. Как отмечает cacke, мьютекс не допускает рекурсивного входа. Кроме того, монитор нельзя использовать за пределами AppDomain. Кроме того, мьютекс можно использовать с такими полезными функциями, как WaitHandle. .WaitAll или WaitAny, где монитор нельзя использовать ни с одной из этих вещей.

Я что-то упускаю?

Нет — в .NET CF Framework вы не можете назвать мьютекс без помощи вызова платформы.

Как использовать мьютекс для защиты ресурса в нескольких приложениях, если я не могу назвать их?

Вы должны назвать их — и вы можете это сделать, вам просто нужно прибегнуть к некоторому вызову платформы. Система на базе Windows CE уже некоторое время поддерживает именованные мьютексы. Вы можете написать вызов P/Invoke, который сделает это самостоятельно:

[DllImport("Coredll.dll")]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool initialOwner, string lpName);

И используйте его как (например) CreateMutex(IntPtr.Zero, false, "MutexName");

Вам также придется написать вызовы P/Invoke для ReleaseMutex и < a href="http://msdn.microsoft.com/en-us/library/ms959878.aspx" rel="nofollow noreferrer">CloseHandle.


В частности, я хочу сделать свое приложение Windows Mobile 6.5 единственным экземпляром.

Именованный мьютекс — одно из решений. Другое решение, которое может сработать для вас, — использовать блокировку файлов.

  1. Создайте файл с именем foo.txt при запуске, если он не существует.
  2. Получите блокировку записи в файле файла с помощью FileShare.None.
  3. Другой экземпляр не сможет установить для него блокировку записи, поскольку первый экземпляр имеет блокировку и не будет делиться ею. Перехватите исключение и завершите программу, поскольку она уже запущена.
  4. Когда программа закроется, очистите блокировку. Даже если процесс аварийно завершится или завершится аварийно, блокировка файла должна быть снята, что позволит запустить другой экземпляр. Что-то вроде этого:

    FileStream stream;
    try
    {
         stream = new FileStream("lock.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
    }
    catch
    {
        MessageBox.Show("Program is already running.");
        return;
    }
    //Put your application code here.
    MessageBox.Show("Program is now running.");
    stream.Close();
    
person vcsjones    schedule 06.10.2011
comment
Это отвечает только на один из четырех заданных вопросов (включая заголовок). Я что-то упускаю? Но что хорошего в безымянном мьютексе? - person Jeffrey L Whitledge; 07.10.2011
comment
@JeffreyLWhitledge Добавлено несколько деталей. - person vcsjones; 07.10.2011
comment
вероятно, стоит хотя бы отметить, что Mutex намного медленнее, чем монитор. - person ctacke; 07.10.2011

Разница между монитором (для которого lock является синтаксическим сахаром) и мьютексом невелика, особенно когда вы смотрите на один процесс. Захватывающий поток может повторно войти в Монитор. Мьютекс не может. Таким образом, если у вас есть рекурсивный алгоритм, который вызывает что-то асинхронно (да, это надуманный пример, но этого должно быть достаточно, чтобы увидеть идею), вы можете предотвратить множественные перекрывающиеся асинхронные вызовы с помощью мьютекса, но не с помощью монитора.

person ctacke    schedule 07.10.2011
comment
ХОРОШО. Но это довольно глупый мьютекс, который они реализовали в CF. ИМО, лучше было бы его вообще исключить. Если они не могут реализовать настоящий мьютекс, то зачем беспокоиться, я думаю, это было моей точкой зрения. - person Tim; 07.10.2011
comment
Они не сделали много реализации. Это оболочка API CreateMutex. Они просто не добавили самую полезную перегрузку. Почему, мы можем только догадываться. - person ctacke; 07.10.2011