簡體   English   中英

使用QAbstractTableModel中多個線程之間共享的數據

[英]using data shared between multiple threads in a QAbstractTableModel

我有一個使用Q_GLOBAL_STATIC實現的單例類,該類包含必須從多個線程訪問的數據結構,我在該類中實現了訪問器函數,該函數將在訪問數據之前鎖定互斥體,以便對共享數據的所有訪問都被序列化。

問題是我想在QAbstractTableModel使用此數據,我可以簡單地使用實現的訪問器函數,並一次從覆蓋的data()columnCount()rowCount()訪問一項。 但是我認為這是不夠的,因為在兩次隨后的對data()調用之間,另一個線程可能會跳入並更改項數(例如rowCount() ),並且該模型的線程可能最終會訪問超出范圍的數據。

我認為我需要在首次重置模型的columnCount()rowCount()之前鎖定互斥鎖,並且僅在將所有數據讀入模型(最后一次調用data() )時才將其解鎖有辦法嗎? 還是我想錯了方向?

我想到了在模型重置時將共享數據結構復制到本地結構(並且僅在復制操作上鎖定了互斥鎖),然后安全地訪問復制的數據,但這不是一個過大的功能嗎? 沒有更有效的解決方案嗎?

在Qt的Model-View框架中,QAbstractItemModel和QAbstractItemView之間的接口根本不是線程安全的,它被設計為僅與一個線程一起使用,該線程必須是GUI線程,即主線程,因為視圖確實是在GUI上繪制的,因此無法在除主(GUI)線程之外的其他線程中安全地完成操作。

因此,模型必須擁有自己的數據,並將其與真實數據同步。 如果數據集很大,則可以依靠fetchMore()避免在每個模型實例中復制整個數據。 查看QtSql的sql模型代碼中完成的操作 這樣一來,您提出的通話間鎖定問題就更容易解決。

如果實際數據持有者對象能夠發出連接到模型實例的信號,您甚至可以事件驅動的方式更新模型。 由於自動/排隊信號連接,模型插槽將在主(GUI)線程中執行,因此不需要使用QAbstractItemModel-QAbstractItemView接口實現線程安全。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM