Какая польза от мьютекса, если вы не можете назвать его? - PullRequest
6 голосов
/ 06 октября 2011

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

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

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

А что хорошего в мьютексе, если у него нет ассоциированного идентификатора?

Я что-то упустил?

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

Ответы [ 2 ]

14 голосов
/ 06 октября 2011

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

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

Безымянный мьютексназывается местным мьютексом.Вы все еще можете использовать его для синхронизации между различными потоками в одном и том же процессе.Такой монитор, как ключевое слово lock, не обладает таким же количеством функций.Как отмечает ctacke , Mutex не допускает рекурсивный вход.Кроме того, монитор нельзя использовать за пределами границ домена приложений.Кроме того, Mutex можно использовать с полезными вещами, такими как 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 и 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();
    
2 голосов
/ 07 октября 2011

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

...