Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QWaitCondition issue



  • Hi Folks,

    I have an unit test code, which should test the thread safety behavioral of a test class. The testcode is the following:
    @
    public: threadWorker() {
    }

    public: virtual void run();

    public: static const int logCountPerThread;
    public: static const int threadCount;
    public: static QWaitCondition waitCondition;
    public: static cacheType logs;

    private: QMutex _sync;
    private: QMutex _end;

    private: cacheType _cache;
    };
    @

    The definition of the static variables:
    @
    cacheType threadWorker::logs;
    const int threadWorker::threadCount = 100;
    QWaitCondition threadWorker::waitCondition;
    const int threadWorker::logCountPerThread = 10000;
    @

    and the worker method itself:
    @
    void threadWorker::run() {
    _sync.lock();
    qDebug() << "thread started, and _sync locked";
    waitCondition.wait(&_sync);

    qDebug() << "woke up";
    for(int count = 0; count < logCountPerThread; count++) {
        _cache.insert(core::logging::log(core::logging::logSeverity::info, QString()).id, 0);
    }
    
    QMutexLocker lock(&_end);
    qDebug() << "_end locked";
    for(cacheType::iterator it = _cache.begin(); it != _cache.end(); ++it) {
        logs.insert(it.key(), 0);
    }
    
    _cache.clear();
    _sync.unlock();
    

    }
    @
    I deploy the threads from the following method:
    @
    void logTest::concurentInsatnce() {
    QVector<threadWorker*> pool;
    for(int count = 0; count < threadWorker::threadCount; count++) {
    pool.push_back(new threadWorker());
    pool.last()->start();
    }

    threadWorker::waitCondition.wakeAll();
    qDebug() << "wake all sent";
    
    for(threadWorker* thread: pool) {
        qDebug() << "start for waiting thread";
        thread->wait();
        qDebug() << "thread exited";
    }
    
    QVERIFY2(threadWorker::logs.size() == threadWorker::logCountPerThread * threadWorker::threadCount,   "unequal object count");
    

    }
    @
    (OFF: I'm sorry for the lot's of debug outputs)

    I observed two main error cases:

    • I start only one thread by adjusting the value of threadWorker::threadCount. In this case, it seems, that the execution is terminated at the "waitCondition.wait(&_sync);", however the debugger output tell, that the wakeAll() signal sent.
    • another error case is the current state, what you can see: I start 100 threads. In this case, I see, that few threads are finising its work, and exit normaly, but another threads "don't see" the wakeAll.

    Can anybody help me?

    Regards,
    Norbert


Log in to reply