.NET Mutex на платформе Windows: что с ними будет после того, как я закончу? - PullRequest
10 голосов
/ 14 августа 2010

У меня есть простая программа .NET, которая проверяет, запущен ли другой экземпляр:

    Mutex mutex = new Mutex(false,"MyMutexName");
    if (!mutex.WaitOne(1))
        return;

    try{
    //do stuff
    }
    catch{ //exceptions}
    finally
    {
        mutex.ReleaseMutex();
    }

У меня вопрос: что именно произойдет с мьютексом, если вы забудете отпустить его после завершения программы? Видно ли это в некоторых компонентах панели управления Windows? Где он живет?

Ответы [ 3 ]

12 голосов
/ 14 августа 2010

Это именованный мьютекс, поэтому он виден и может быть открыт в других процессах. Windows использует простой счетчик ссылок на дескриптор. Если вы не используете Dispose () явно, то финализатор закроет для вас дескриптор. Если ваша программа сильно бомбит и никогда не запускает финализатор, то Windows сделает это, когда очистит ресурсы, используемые вашей программой.

Это автоматически уменьшит счетчик ссылок. Если это считается до нуля (никакие другие процессы не имеют открытого дескриптора), то объект ядра освобождается.

Другими словами: у вас нет проблем, независимо от того, как все плохо. Фактический объект-мутант находится в пуле памяти ядра. Это можно увидеть с помощью инструмента WinSbj от SysInternals.

3 голосов
/ 14 августа 2010

С MSDN

Если поток завершается во время владения мьютекс, мьютекс называется отказались. Состояние мьютекса установить сигнал и следующее ожидание нить получает право собственности. Если никто не владеет мьютекс, состояние мьютекса сигнализировал. Начиная с версии 2.0 .NET Framework, AbandonedMutexException добавляется в следующая нить, которая приобретает мьютекс. До версии 2.0 .NET Framework, исключений не было выброшены.

Внимание

Заброшенный мьютекс часто указывает на серьезная ошибка в коде. Когда поток выходит без освобождения мьютекс, структуры данных защищены мьютексом не может быть в последовательное состояние. Следующая тема запросить право собственности на мьютекс обработать это исключение и продолжить, если целостность структур данных можно проверить.

В случае общесистемного мьютекса заброшенный мьютекс может указывать на то, что заявка была прекращена внезапно (например, используя Диспетчер задач Windows).

3 голосов
/ 14 августа 2010

Мьютексы - дескрипторы уровня ОС.Они закроются, когда ваш процесс закроется (если вы не закроете их раньше, то есть.)

edit

Хорошо, я явно неправильно понял пример и вопрос.Если вы просто пытаетесь определить, существует ли другой экземпляр, вы создадите именованный мьютекс (или подобный объект) и просто проверите его существование, не блокируя его.

Вызов WaitOne блокируетна него вступает во владение, а ReleaseMutex избавляется от него (до тех пор, пока нет дополнительных вызовов на WaitOne).Если вы завершаете поток, не освобождая мьютекс полностью, он оставляет объект в плохом состоянии, как объясняется в тексте, который цитирует Мика.

Я принял ваш вопрос о том, закрываете ли вы дескриптор до завершения процесса, что совсем другое.

дополнительная

На уровне SDK [API] [1] вы можете вызвать CreateMutexс ожиданием сбоя, когда мьютекс с тем же именем уже был создан.В .NET (ну, по крайней мере, в 4.0) есть [конструктор] [2], который заполняет createdNew bool.

[1]: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx CreateMutex

[2]: http://msdn.microsoft.com/en-us/library/bwe34f1k(v=VS.90).aspx Мьютекс

...