QReadWriteLock рекурсия

Я использую QReadWriteLock в рекурсивном режиме.

Этот код сам по себе не имеет смысла, но у меня возникают следующие проблемы:

lock->lockForWrite();
lock->lockForRead();

lockForRead заблокирован. Обратите внимание, что это в рекурсивном режиме.

Я вижу, что запись - это "превосходящая" блокировка, она позволяет мне читать и записывать защищенные данные, а блокировка чтения позволяет только чтение.

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

Из исходных кодов qreadwritelock.cpp я вижу, что нет никаких попыток заставить его работать так, как мне бы хотелось. Так что это не ошибка, а функция, которую я считаю отсутствующей.

У меня вопрос такой: должна ли быть разрешена такая рекурсия? Есть ли какие-либо проблемы, которые возникают из-за такой реализации и какими они будут?

2 ответа

Из документов QReadWriteLock:

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

Итак, как вы говорите, это так, как это работает. Лично я не понимаю, как разрешение чтения в том же потоке, что и запись, заблокированная для записи, может вызвать проблемы, но, возможно, это требует неэффективной реализации блокировки?

Вы можете попробовать задать вопрос на форумах QT, но я сомневаюсь, что вы получите окончательный ответ. Почему бы вам не взять исходный код QT как стартер и попробовать себя, если это то, что вам нужно. Написание объектов синхронизации может быть сложным, но это хорошее учебное упражнение.

Я нашел этот вопрос, когда сам искал ту же функциональность. Размышляя о реализации этого самостоятельно, я понял, что определенно возникает проблема, возникающая при этом:

Таким образом, вы хотите обновить блокировку с общего (чтение) до эксклюзивного (запись). дела

lock->unlock();
lock->lockForWrite();

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

lock->changeModus(WRITE);

или что-то подобное, вы создадите тупик. Чтобы получить блокировку записи, блокировка блокируется до тех пор, пока не будут сняты все текущие блокировки чтения. Поэтому здесь несколько потоков будут блокировать ожидание друг друга.

Другие вопросы по тегам