Требуется: межпроцессная синхронизация, которая не страдает от AbandonedMutexException - PullRequest
3 голосов
/ 17 марта 2009

У меня есть несколько потоков, которые получают мьютексы, а затем завершают работу.

Мьютексы хранятся в главном хранилище и правильно освобождаются, когда программа существует. Однако, когда поток, который выделил Mutex, существует, мьютекс освобождается автоматически и в последующем получает AbandonedMutexException (также согласно документации ).

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

Примечание - Я ищу механизм синхронизации между процессами с семантикой, аналогичной Mutex.

Ответы [ 3 ]

6 голосов
/ 17 марта 2009

Ответ на вопрос

AFAIK такого класса Mutex не существует. AbandonedMutexException довольно раздражает, но представляет реальную ситуацию, для которой не существует автоматического решения.

Если у вас кросс-процессный или даже кросс-поточный обмен данными, вы должны учитывать тот факт, что любая из участвующих сторон может быть неожиданной и внезапно прерванной по любому числу причин. Mutex существует для защиты ресурсов, если поток, в котором он находится, хранится в Mutex, у ОС нет никакого способа гарантировать, что он оставит данные любым согласованным образом. Это очень важно, потому что это означает, что отказ от потока может сделать недействительными определенные инварианты, от которых зависят другие потоки.

AbandonedMutexException - это способ предупреждающего предупреждения "случилось что-то плохое, и теперь вы находитесь в неопределенном состоянии". Других ресурсов для операционной системы здесь нет.

Ответ на ваш ответ

EventWaitHandle отличается от Mutex и служит различным целям.

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

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

Вы можете использовать EventWaitHandle для реализации формы безопасности потоков. Вместо владения блокировкой, являющейся ключом к доступу к ресурсу, сигнал от события является ключом к доступу к ресурсу. Однако дьявол снова в деталях.

  1. Кто отвечает за оповещение о событии? С мьютексом каждый поток по сути кричит "me me me", и ОС выбирает один поток, чтобы выиграть. С EventWaitHandle вы будете нести ответственность за решение, когда следующий поток будет запущен.
  2. Что происходит, когда кто-то убивает процесс с помощью taskmgr? Что, если уничтоженный процесс имеет поток, в настоящее время отвечающий на событие в EventWaitHandle?
  3. 2, но что произойдет, когда предмет, который будет сигнализировать о ручке ожидания, будет снят? Вы должны учитывать это, чтобы избежать тупика.

1 голос
/ 17 марта 2009

Похоже, EventWaitHandle делает то, что я хочу. У него есть конструктор, который принимает имя, поэтому он идеально подходит для межпроцессной синхронизации и не имеет этой проблемы.

0 голосов
/ 09 июля 2012

Ничто не мешает вам использовать Mutex после получения AbandonedMutexException. Из документа :

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

Конечно, это предполагает, что вы знаете , что вы (и ваши потоки) делаете во время их сбоя, и это в основном означает, что поток-получатель мог бы также освободить мьютекс до выхода. *

Так что, в конце концов, ваше собственное решение использования EvenWaitHandle лучше, чем мьютекс.

...