System::Threading::Mutex, вызывается из несинхронизированного блока кода. Неожиданный тупик
В попытке избавить мой графический интерфейс от условий гонки и взаимных блокировок у меня есть следующая функция, которую я вызываю из c'tor, и всякий раз, когда мне нужен сервис, который разделяет мои именованные mutex
предоставить свой вклад:
void EnvCapt::FireServiceAndOrHold() {
try {
mutTimerSyncEx->ReleaseMutex();
Thread::Sleep(100); //Time enough for the service to complete.
if (!mutTimerSyncEx->WaitOne(3 * int_ms)) {//int_ms = the polling period
//Must've been doubly locked or worse.
mutTimerSyncEx->ReleaseMutex();
FireServiceAndOrHold();
}
} catch (Exception ^ ex) {
//Released unheld mutex. Retake control.
mutTimerSyncEx->WaitOne();
FireServiceAndOrHold();
}
}
Это работает относительно хорошо, но я звоню по этому поводу, прежде чем позволить службе, теперь я готов принять ввод, поэтому он никогда не пытается ждать, пока я не отпущу мьютекс для него. Прежде чем я попытаюсь изменить порядок вещей, я хотел бы знать, что происходит с вышеуказанной функцией. Я получаю ошибку:
Метод синхронизации объекта был вызван из несинхронизированного блока кода.
Потому что называть релиз на mutex
это не было WaitOne
Я брослю, я поймаю это, зная, что я свободен, чтобы завладеть этим и продолжить. Но я не прав. Он навсегда висит на WaitOne()
заявление. Я знаю, что другой процесс делает все это время, потому что он заперт в моем втором окне отладчика. Это не касается мьютекса.
ОБНОВИТЬ
Я попытался изменить порядок, который я сначала предложил, это казалось хорошим, но теперь я нахожу, что мьютекс является всего лишь видом Global, несмотря на то, что у него есть Global \ name.
Это разделяется, потому что, когда мой GUI c'tor это
firstInstance
ложно, поэтому я пытаюсь взять его под контроль.Это не является общим, потому что, когда вызовы GUI
WaitOne()
на нем графический интерфейс блокируется на неопределенный срок. В то время как сервис танцует прямо через призыв кWaitOne()
без заботы в мире.
1 ответ
Я просто подумал, что может быть не так для вас там:
Подсказка: вы не можете освободить мьютекс от имени другого процесса! Другой процесс должен освободить мьютекс, если он его держит:
Process 1: Process 2:
============ =============
WaitOne (locks the mutex)
// do work WaitOne (awaits the mutex)
// do more work
// done
ReleaseMutex ------> WaitOne returns from the wait _with
the mutex locked_