Невозможно получить блокировку на QMutex

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

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

Я проверил, что мьютексы всегда блокируются и разблокируются из одного и того же потока - фактически, почти всегда в пределах одного блока фигурных скобок - и в моем последнем раунде устранения неполадок я заменил все мои голые QMutexes на определенные объекты 'nMutex' следующее:

class nMutex : public QMutex
{
public:
    nMutex() : QMutex(),
               locks(0),  
    {}

    void lock(const char * callingFilename, int callingLineNo) 
    { 
        // QMutex::lock();     // Frequently hangs, so tried the following instead...
        if (!tryLock(1000))
        {
            printf("Cannot obtain mutex at line %d of %s; locks = %d",
                   callingLineNo, callingFilename, locks);
        }
        else
        {
            if (isRecursive())
                ++locks;
            else
                locks = 1;
        }
    }

    bool tryLock(int timeout = 0)  // Hides rather than overrides QMutex's tryLock, 
                                   // which is not virtual
    {
        bool result = QMutex::tryLock(timeout);
        if (result)
        {
            if (isRecursive())
                ++locks;
            else
                locks = 1; 
        }
        return result;
    }

    bool isLocked() const { return (locks > 0); }

    int lockDepth() const { return locks; }

    void unlock()
    {
        if (!locks) return;
        QMutex::unlock();
        if (isRecursive())
            --locks;
        else
            locks = 0; 
    }

private:
    int locks;
};

... и заменил все мои вызовы mutex.lock() на

mutex.lock(__FILE__, __LINE__).

Я обнаружил, что это довольно часто терпит неудачу, и когда это происходит, он всегда сообщает "locks = 0" - другими словами, ни у одного другого потока уже нет мьютекса, и все же поток, пытающийся его получить, не может его получить., Сбои происходят, по-видимому, случайно, независимо от того, где в моем коде сделан вызов mutex.lock().

В настоящее время я вижу две возможности:

(1) Я очень глуп, и не вижу, что что-то не так с вышеуказанным подходом, или

(2) В QMutex есть ошибка. Это кажется маловероятным, поскольку я не видел отчетов, и я пробовал это по крайней мере в трех версиях Qt 5.3 и 5.4 (включая самую последнюю версию 5.4.1).

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

0 ответов

Другие вопросы по тегам