2012-02-01 2 views
0

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

Acquire mutex 
Acquire mutex 

// do something here 

Release mutex 

// still has mutex lock at this point!! 

Я знаю, что могу просто использовать bool здесь, но хотел знать, существует ли что-то уже существующее.

Спасибо.

ответ

0

Если вы используете определенную платформу реализацию мьютекса (Win32?) - то вам следует обратиться к документации этой платформы.

Если вы используете стандартный мьютекс C++ 11 - std :: mutex, вместо этого переключитесь на std :: recursive_mutex. Обратите внимание, что вам нужно будет вызвать unlock() для каждого вызова lock().

+2

«Прочитать документацию» не является ответом на переполнение стека. –

0

Исследуйте RAII. Это не позволит вам беспокоиться об этой проблеме.

+0

Предложив обернуть его в класс/структуры с дополнительным BOOL для если его заблокировали или нет? ... (этот комментарий может быть несколько преждевременным после 5-минутного google относительно RAII) – Cheetah

+0

+1. Предложение Павла хорошее. У этого класса будет один член - мьютекс (ссылка). Приобретайте в конструкторе Release в деструкторе. Исключительно безопасный и не нужен какой-либо bool. Посмотрите пример в первом ответе здесь: http://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about –

+2

I не вижу, как это поможет здесь. Рекурсивный вызов не приведет к активации аспекта выпуска RAII до следующего вызова. –

0

Какой API вы используете? Это важно, потому что, если это, например, Win32 API дважды вызывает WaitForSingleObject в одном потоке на одном мьютексе, вам не нужно вызывать ReleaseMutex два раза.

Однако это рискованны коды в любом случае

1

Слишком долго для комментария, так извинений это ответ ..

IMO, любая конструкция, которая требует рекурсивной блокировки, скорее всего, до конца носовых демонов. Переконфигурируйте код, чтобы одна и та же блокировка не могла быть получена несколько раз одним и тем же потоком. ИМО хорошая практика заключается в том, чтобы никогда не вызывать публичные функции (которые должны блокироваться) из других публичных функций (которые также блокируются), и все частные функции никогда не должны блокироваться, т. Е. Они могут быть вызваны только публичными методами (которые заблокированы).

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

все-в-все, избежать рекурсивные мьютексы, если вы можете ...

+0

Однако рекурсивные мьютексы действительно существуют. –

+0

@ edA-qamort-ora-y, для тех, кто достаточно мазохист, чтобы рисковать по этому маршруту ...;) – Nim

Смежные вопросы