Der*_*rek 3 c++ qt design-patterns
我正在尝试为我正在研究的算法做出一些设计决策.我认为我想使用信号和插槽来实现观察者模式,但我不确定一些事情.
这是我正在努力的算法:
1.) Load tiles of an image from a large file
1a.) Copy the entire file to a new location
2.) Process the tiles as they are loaded
3.) If the copy has been created, copy the resulting data into the new file
Run Code Online (Sandbox Code Playgroud)
所以我设想有一个像loadAllTiles()这样的函数的类,它会发出信号告诉processTile()另一个tile已经准备好被处理,同时继续加载下一个tile.
processTile()将执行一些计算,并在完成后,向writeResults()发出信号,表示已准备好写入一组新的结果数据.writeResults()将验证复制是否完成,并开始写入输出数据.
这听起来合理吗?有没有办法在tile中加载loadAllTiles(),以某种方式将该数据传递给processTile(),然后继续加载下一个tile?我正在考虑设置一个类似的列表来存储准备好处理的区块,另一个列表用于准备好写入磁盘的结果区块.我想我的缺点是我必须以某种方式保持这些列表,以便多个线程不会尝试添加/删除列表中的项目.
感谢您的任何见解.
在你的问题中并不完全清楚,但似乎你想将工作分成几个线程,这样在完成加载整个集合之前就可以开始处理tile.
考虑多线程处理流水线架构.为每个任务分配一个线程(加载,复制,处理),并通过Producer-Consumer队列(又名BlockingQueue)在任务之间传递切片.更准确地说,将指针(或共享指针)传递给tile,以避免不必要的复制.
似乎没有要在Qt的一个现成的线程安全的BlockingQueue类,但可以使用卷起自己的QQueue
,QWaitCondition
和QMutex
.以下是一些灵感来源:
虽然在Qt中没有现成的BlockingQueue,但似乎使用带有该Qt::QueuedConnection
选项的信号和插槽可能用于相同的目的.这篇Qt 博客文章对信号和插槽进行了这样的使用.
您可能希望将此管道方法与内存池或免费的切片列表结合使用,以便已在您的管道中回收已分配的切片.
这是管道的概念草图:
TilePool -> TileLoader -> PCQ -> TileProcessor -> PCQ -> TileSaver -\
^ |
\----------------------------------------------------------------/
Run Code Online (Sandbox Code Playgroud)
where PCQ
表示Producer-Consumer队列.
要利用更多并行性,您可以在每个阶段尝试线程池.
您还可以考虑查看英特尔的线程构建模块.我自己没试过.请注意开源版本的GPL许可证.