Qt: Как синхронизировать доступ к данным из нескольких потоков в настройке модели / вида? - PullRequest
1 голос
/ 20 декабря 2011

Как синхронизировать доступ к данным, доступ к которым осуществляется из нескольких потоков, в настройке модели / представления Qt?

Я использую QTableView с классом Model.

Model расширяет QAbstractTableModel и имеет экземпляр пользовательского класса Net, который содержит фактические данные, которые будут отображаться в вызовах от QTableView до data() (доступ к которым Model::data())

Мой класс прослушивает сетевые данные и работает в отдельном потоке, из которого он обновляет свои данные (простой массив фиксированного размера из 10 строк).

Данные в моем классе должны быть доступны как потоку, который постоянно обновляет их, так и из Qt GUI, вызывая data() в Model.

Я бы предположил, что мне нужно использовать мьютекс для синхронизации доступа к моему массиву строк, но QAbstractTableModel::data() - это метод const, поэтому я не могу заблокировать boost::mutex в нем.

Каков общий шаблон для синхронизации доступа к данным в классе, который расширяет QAbstractTableModel и предоставляет данные для QTableView?

1 Ответ

1 голос
/ 20 декабря 2011

Я не думаю, что классы представления элементов Qt (например, QAbstractTableModel) и несколько потоков будут очень хорошо работать вместе.Проблема заключается в том, что класс QAbstractTableModel должен уведомлять все связанные классы представлений при каждом изменении данных, а также классы представлений должны иметь возможность считывать данные из модели данных в любое время.Реализовать это было бы сложно (в любом случае, эффективно), если обновления и данные принадлежат другому потоку.Я подозреваю, что любое многопоточное решение, которое вы придумали, нужно было бы сериализовать так сильно, что в любом случае одновременно работал бы только один из двух потоков, после чего вы фактически вернулись к однопоточной программе, простоочень запутанный дизайн:)

Мое предложение было бы переместить вашу 10-строковую базу данных в основной поток / Qt, если это возможно.Ваши сетевые операции также могут быть перемещены в основной поток (используйте объекты QSocketNotifier и убедитесь, что все операции ввода-вывода неблокированы, чтобы он не мог удерживать цикл событий Qt и ухудшать производительность графического интерфейса);или вы можете хранить сеть в отдельном сетевом потоке и просто сделать так, чтобы сетевой поток отправлял сообщения обновления в основной поток / Qt, сообщая главному потоку / Qt, как обновить базу данных / модель таблицы.Ключ заключается в том, чтобы все операции чтения и записи в базу данных модели данных выполнялись главным потоком / Qt.

...