设计模式、Qt 模型/视图和多线程
我正在创建一个显示市场数据并以其他形式使用它的应用程序.我将市场数据存储在地图中说std::map
.让我举一个如何使用这张地图的用例.
I am creating an application which displays the market data and uses it in some other forms too. I store market data in a map say
std::map<tickerId, StockData>
. Let me give one used case of how this map can be used.
- 网络在时间 t 发送一个封装股票数据的数据包.
updatePrice(tickerId, latestPrice)
- 更新地图中的股票数据.现在,多个线程可以访问/更新数据.因此必须锁定映射以进行线程安全操作.这是第一个问题,我是否也需要锁定底层数据以进行更新?
- 新股票数据有多种用途,比如 IBM 的价格更新,然后我需要更新我投资组合中 IBM 的价值.以及在屏幕上显示新数据.并且可以同时使用多个其他用途.
updatePosition(tickerId, price)
和updateStockScreen(tickerId, price)
.此外,将 GUI 更新与位置更新分开也很重要,因为 GUI 不是应用程序的主要优势. - 我只是对如何实现这种类型的设计感到困扰.我在 QT 中阅读了模型/视图设计以显示数据,但如果视图线程从同一地图读取,则必须将其锁定.这会导致设计缓慢/低效.每次视图从模型中读取时,都需要锁定模型.这在实时 GUI 中是首选吗?
- 总而言之,我将许多不同的对象存储为地图.并且对象是实时更新的.我需要更新它们,然后在不同的位置使用它们.如果有人能给我一个关于如何实现此类设计的小例子,那就太好了.
- network sends a data packet encapsulating the stock Data at time t.
updatePrice(tickerId, latestPrice)
- update the stock data in the map. Now, multiple threads can access/update the data. So the map has to be locked for thread-safe operations. Here is the first question, do I need to lock the underlying data too for updates?
- There are multiple uses of the new stock data, say, there is a price update on IBM, then I need to update the value of IBM in my portfolio. As well as display the new data on a screen. And there can be several other simultaneous uses.
updatePosition(tickerId, price)
andupdateStockScreen(tickerId, price)
. Also, separting Gui updates from position update is important as GUI is not the main strength of the application. - I am just troubled about how to implement this type of design. I read about Model/View Design in QT to display data but if View thread reads from the same map, it has to be locked. This leads to an slow/inefficient design. Every time view reads from the model, the model needs to be locked. Is this preffered in real-time GUIs?
- To summarize, I have stored a lot of different objects as maps. And objects are updated in realtime. I need to update them and then use them at various locations. It would be great if someone can give me a small example on how to implement such designs.
对有用书籍的一些参考也受到赞赏.
Some references to useful books are appreciated too.
我是新手,试图用自己的知识取得太多成就,所以如果我问了愚蠢/格式错误的问题,请原谅我.
I am new and trying to achieve too much with my little knowledge so forgive me if I have asked stupid/ill-formed questions.
谢谢湿婆
推荐答案
从概念上讲,您希望模型在一个线程上,而视图在另一个线程上,我曾研究过这一点.
It sounds conceptually like you want the model on one thread and the view on another, which I looked into at one point.
如果是这样...并且您的模型通过视图小部件是只读的,那么是的,您必须锁定.我认为这样做会破坏模型/视图分离提供的解耦"的优雅.但它可以工作.
If so...and your model is read-only through the view widget then yes, you have to lock. I'd argue that doing so undermines the elegance of the "decoupling" provided by the model/view separation. But it could be made to work.
但是...如果您的模型是通过视图读写的,则不可能完全正确执行,因为通知槽的排队性质.这是我在 qt-interest 邮件列表上关于该主题的邮件列表对话的存档:
However...if your model is read-write through the view it's not possible to do correctly at all because of the queued nature of the notification slots. Here's an archive of a mailing list conversation I had on the qt-interest mailing list on the topic:
http://blog.hostilefork.com/qt-model-view-不同的线程/
简短的版本是我认为模型不可行
在非 GUI 线程上进行修改...无论模型是否
数据已被读/写锁保护.如果我在收集什么
是正确的,那么 Qt 可能应该断言一个模型和
它的视图具有相同的线程关联(现在似乎没有这样做)"
"The short version is that I don't think it's feasible for a Model to
be modified on a non-GUI thread...regardless of whether the model's
data has been protected with read/write locks. If what I'm gathering
is correct, then Qt should probably have an assert that a model and
its view have the same thread affinity (it doesn't seem to do that now)"
随后由 KDE 开发人员进行的单元测试验证了这一点.
A subsequent unit test by a KDE developer verified this.
我觉得解决这个问题的最好方法是将模型和视图保持在同一线程上,并且只在 GUI 线程中修改模型.所以如果工作线程希望改变它,那么它应该使用一个信号.
I feel the best way to work around this is to keep the model and the view on the same thread, and only modify the model in the GUI thread. So if the worker thread wishes to change it then it should use a signal.
工作人员是否需要保留自己创建模型的数据副本(或者是否需要在用户通过视图更改模型时收到通知以使其保持最新状态)取决于您的应用.如果我理解正确的话,听起来您可能只需通过信号/插槽传送更新并将它们忘记在工作人员身上就可以逃脱...
Whether the worker needs to keep their own copy of the data from which the model was created (or if it needs to get notifications to keep that up to date when the user changes the model through the view) depends on your app. If I understand you correctly, it sounds like like you could probably get away with just ferrying the updates through signal/slots and forgetting them on the worker...
相关文章