PDA

View Full Version : QReadWriteLock locks for reading...but why?



Qtonimo
28th August 2012, 08:18
Hi,
I have a big ressource and several Threads want to read the ressource simultanous. The ressource get exchanged every hour. While exchanging the read-access should be blocked. I solve this with QReadWriteLocker.
But why the Threads are locked for reading. If one thread reads a lot of data, all the other threads are locked, because of QReadLocker.

I just want to lock the threads, while exchanging...

Thanks, bye

ChrisW67
28th August 2012, 09:40
If you QReadWriteLock::lockForWrite() the file to write it blocks users in other threads (as documented) until you unlock().

What exactly does "exchanged" mean?

Qtonimo
28th August 2012, 09:46
Thanks for reply :)

Exchanged means renewed...

While renew() the read-access should be blocked....


void DataManager::renew(){
QWriteLocker(&lock);
QList<Data*>* data = getnewdata();

//clear old data
delete this->data;

//assign new data
this->data = data;
}


Simultaneous read should be possible, but QReadLocker prevent this.

Qtonimo
28th August 2012, 15:25
Nobody can help?
I just want to know why several Threads aren't able to read the same container at the same time?

ChrisW67
29th August 2012, 00:24
Active QReadLockers don't block other read locks but an open write lock will.

Here's an example showing three concurrent read locks and no blocks:


#include <QtCore>
#include <QDebug>

class SlowReader: public QObject {
Q_OBJECT
public:
SlowReader(int number, QReadWriteLock *lock, QObject *p = 0)
: QObject(p), m_num(number), m_lock(lock)
{
}

public slots:
void process() {
QReadLocker locker(m_lock);
qDebug() << QString("Thread %1 started").arg(m_num);
for (int i = 0; i < 10; ++i) {
sleep(1);
qDebug() << QString("Thread %1 reading").arg(m_num);
}
qDebug() << QString("Thread %1 done").arg(m_num);
emit finished();
}

signals:
void finished();

private:
int m_num;
QReadWriteLock *m_lock;
};


int main(int argc, char **argv) {
QCoreApplication app(argc, argv);

QReadWriteLock lock;
for (int i= 0; i < 3; ++i) {
QThread* thread = new QThread;
SlowReader *worker = new SlowReader(i, &lock);
worker->moveToThread(thread);

QObject::connect(thread, SIGNAL(started()), worker, SLOT(process()));
QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}

return app.exec();
}

#include "main.moc"

Each thread holds a read lock for the entire 10 seconds it takes to do the 10 reads.

Qtonimo
29th August 2012, 11:58
Thank you ChrisW67 for the test app.
It convinced me. :)