Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 无法获取QMutex上的锁_Qt_Qmutex - Fatal编程技术网

Qt 无法获取QMutex上的锁

Qt 无法获取QMutex上的锁,qt,qmutex,Qt,Qmutex,我目前正在开发的应用程序是多线程的,线程之间共享大量资源。我使用qmutex是为了保护共享资源,尽管在实践中,试图同时锁定同一互斥锁的不同线程之间很少会发生争用 尽管如此,我还是发现我的应用程序频繁地陷入停顿。当我中断执行并检查发生了什么时,我发现一个线程被暂停,因为它无法获得所需的互斥锁 我已经检查过互斥锁总是从同一线程锁定和解锁的——事实上,几乎总是在同一个花括号块中——在我的最新一轮故障排除中,我用定义如下的“nMutex”对象替换了所有裸露的QMUTEX: class nMutex :

我目前正在开发的应用程序是多线程的,线程之间共享大量资源。我使用qmutex是为了保护共享资源,尽管在实践中,试图同时锁定同一互斥锁的不同线程之间很少会发生争用

尽管如此,我还是发现我的应用程序频繁地陷入停顿。当我中断执行并检查发生了什么时,我发现一个线程被暂停,因为它无法获得所需的互斥锁

我已经检查过互斥锁总是从同一线程锁定和解锁的——事实上,几乎总是在同一个花括号块中——在我的最新一轮故障排除中,我用定义如下的“nMutex”对象替换了所有裸露的QMUTEX:

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()的所有调用替换为

我发现这经常失败,当它失败时,它总是报告“locks=0”-换句话说,没有其他线程已经有互斥锁了,但是试图获取互斥锁的线程却无法获取互斥锁。失败似乎是随机发生的,无论在我的代码中调用mutex.lock()的位置如何

目前我可以看到两种可能性:

(1) 我很愚蠢,没有发现上述方法有什么问题,或者

(2) QMutex中有一个bug。这似乎不太可能,因为我没有看到任何报告,我已经在Qt5.3和5.4的至少三个版本(包括最新的5.4.1)中尝试过


有没有办法测试这两种可能性中哪一种最有可能是正确的?例如,在无法获取互斥锁的情况下,是否有办法找出具体原因?

您的上述方法至少有一个缺陷:
类中的locks
字段在不同线程的lock()和unlock()之间不同步,其值可能错误。无论如何,互斥体是非常基本的生物,我简直不敢相信QMutex中有bug。我通常只是通过仔细分析所有线程的调用堆栈来调试这些问题:必须有某个互斥锁以前被锁定但尚未解锁的地方。我不确定我是否看到了这一点,因为locks变量只有在底层QMutex被锁定或解锁后才被更新。无论如何,我发现了另一个可能是关键的问题。由于QMutex::lock()不是虚拟的,因此形式为QMutexLocker locker(&myNMutex)的指令通过传递我仔细的引用计数机制来调用QMutex::lock(),而不是nMutex::lock()!在我的代码中,我混合了QMutexLockers和manual lock()-unlock()对。我已经进行了重构,将QMutexLockers与qmutex一起使用,现在看来一切正常。
mutex.lock(__FILE__, __LINE__).