У меня есть одноэлементный класс, реализованный с использованием Q_GLOBAL_STATIC
который содержит структуру данных, доступ к которой должен быть из нескольких потоков, я реализовал функции доступа в классе, которые блокировали бы мьютекс перед доступом к данным, чтобы все обращения к общим данным были сериализованы.
Проблема в том, что я хочу использовать эти данные в QAbstractTableModel
Я могу просто использовать функции доступа, которые я реализовал, и получить доступ к одному элементу за раз из моего переопределенного data()
, columnCount()
а также rowCount()
, Но я думаю, что этого недостаточно, поскольку между двумя последующими вызовами data()
например, может перейти другой поток и изменить количество элементов (rowCount()
), и поток модели может в конечном итоге получить доступ за пределами данных.
Я думаю, что мне нужно заблокировать мьютекс перед самым первым вызовом columnCount()
а также rowCount()
сброса модели и разблокируйте ее только после считывания всех данных в модель (после последнего вызова data()
), есть ли способ сделать это? или я ошибаюсь?
Я думал о копировании общей структуры данных в локальную при сбросе модели (и мьютекс заблокирован только для операции копирования), и после этого безопасный доступ к скопированным данным, но разве это не перебор? нет ли более эффективного решения?
В каркасе Model-View Qt интерфейс между QAbstractItemModel и QAbstractItemView вообще не является потокобезопасным, он предназначен для использования только с одним потоком, который должен быть потоком GUI, т. Е. Основным потоком, так как view выполняет рисование в GUI, который не может быть безопасно сделано в другом потоке, чем основной (GUI) поток.
Поэтому модель должна хранить свои собственные данные и синхронизировать их с реальными данными. Если ваш набор данных большой, вы можете положиться на fetchMore (), чтобы избежать копирования всех данных в каждом экземпляре модели. Посмотрите, что сделано в Код QtSql для sql-моделей. Тогда проблему блокировки между вызовами легче решить.
Вы даже можете обновить модель на основе событий, если реальные объекты-держатели данных могут излучать сигналы, связанные с экземпляром модели. Благодаря автоматическим / поставленным в очередь сигнальным соединениям слоты модели будут выполняться в основном потоке (GUI) и, следовательно, не должны быть поточно-безопасными с интерфейсом QAbstractItemModel-QAbstractItemView.
Других решений пока нет …