QMutex застрял в заблокированном состоянии - PullRequest
2 голосов
/ 23 января 2010

У меня есть функция, которая является частью класса, и в этой функции есть mutex.lock в начале функции и mutex.unlock непосредственно перед ее возвратом. Теперь я столкнулся с ситуацией, когда мьютекс застрял в заблокированном состоянии. Что может быть сделано, если эта функция - единственное место, где я использую этот мьютекс для блокировки и разблокировки. Функция вызывается из основного потока и из 1 или 2 других QThreads.

ОБНОВЛЕНИЕ: проблема была в том, что поток не спал между вызовами функций. Может быть, недостаток сна очень быстро перебил мьютекс? Вы также можете вызвать yieldCurrentThread ();

Ответы [ 4 ]

5 голосов
/ 23 января 2010

Если в функцию выдается исключение, unlock() в конце может не выполняться. Чтобы в таких случаях разблокировать QMutex, вы можете выполнить блокировку с помощью объекта QMutexLocker. Этот объект автоматически разблокирует мьютекс после его уничтожения, даже если это происходит во время разматывания стека после исключения.

0 голосов
/ 23 февраля 2011

В Mac OS X у меня были зависания QMutex даже в 100% правильной логике. Я сделал вызов обертки вокруг QMutex, который увеличил / уменьшил атомный счетчик ссылок, и QMutex завис в месте, где счетчик ссылок означал отсутствие удержанного мьютекса.

Это случилось со мной один раз в Qt3, и еще раз в недавнем Qt (4.6.2 или 4.7.0, я не помню). Замена QMutex пользовательским классом, который идет непосредственно к примитивам ОС, - решила проблему.

Обратите внимание, однако, что эта проблема возникла только на OS X в моем случае. В Windows тот же код работал отлично.

0 голосов
/ 27 января 2010

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

0 голосов
/ 23 января 2010

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

Есть ли какие-либо блокирующие звонки внутри кода блокировки / разблокировки?

Из Qt QMutex Документация:

Когда вы вызываете lock () в потоке, другие потоки, которые пытаются вызвать lock () в том же месте будет блокировать до поток, который получил вызовы блокировки разблокировать ()

...