Режим рекурсии QReadWriteLock не работает - PullRequest
1 голос
/ 06 декабря 2011

Под 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 ]

2 голосов
/ 12 февраля 2012

Я наконец нашел главное отличие.Когда QReadWritelock объявлен как Рекурсивный, Readlock из одного потока считается только одной блокировкой.Следовательно, последовательная блокировка для чтения в той же теме не может быть заблокирована ожидающей блокировкой записи.Когда блокировка объявлена ​​нерекурсивной, это может произойти и привести к очень плохим взаимоблокировкам.

0 голосов
/ 03 февраля 2012

Я полагаю, что режим QReadWriteLock::NonRecursive влияет только на блокировки записи.

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

...