Режим рекурсии QReadWriteLock не работает
В Linux qt 4.7.4 с использованием gcc 4.4.3 следующий код прекрасно компилируется и не выдает ошибку времени выполнения.
class TestThread: public QThread {
private:
QReadWriteLock mutex;
public:
bool mStop;
TestThread(): mutex(QReadWriteLock::NonRecursive),mStop(false) {}
void run() {
while(!mStop) {
mutex.lockForRead();
qDebug() << "Tread running";
msleep(100);
}
}
};
Блокировка блокируется одним и тем же потоком несколько раз, и ничего не происходит. Согласно руководству http://doc.qt.io/archives/qt-4.7/qreadwritelock.html
блокировка должна блокироваться только одним потоком. Это серьезная ошибка или я неправильно понимаю руководство?
В ответе Крису: Блокировка должна быть разблокирована несколько раз и в NonRecursive, следующий код никогда не печатает "Запись", если одна разблокировка закомментирована.
class TestThread: public QThread {
private:
QReadWriteLock mutex;
public:
TestThread(): mutex(QReadWriteLock::NonRecursive){}
void run() {
mutex.lockForRead();
mutex.lockForRead();
qDebug() << "Tread running";
//mutex.unlock();
mutex.unlock();
mutex.lockForWrite();
qDebug() << "Writing";
mutex.unlock();
msleep(50);
}
};
int main(int argc, char *argv[]) {
TestThread myThread;
myThread.start();
usleep(500000);
myThread.terminate();
}
2 ответа
Я наконец-то нашел главное отличие. Когда QReadWritelock объявлен как Рекурсивный, Readlock из одного потока считается только одной блокировкой. Следовательно, последовательная блокировка для чтения в той же теме не может быть заблокирована ожидающей блокировкой записи. Когда блокировка объявлена нерекурсивной, это может произойти и привести к очень плохим взаимоблокировкам.
Я думаю, QReadWriteLock::NonRecursive
Режим влияет только на блокировки записи.
Попробуйте получить блокировку записи в нерекурсивном режиме два раза из одного потока, и я думаю, что вы получите поведение, которое вы ожидали.