多线程任务总体进度报告的设计模式
Design Pattern for multithreaded task overall progress report
我有一个带有IJobMaker
实体的库,它创建了一定数量的IJob
对象,这些对象将在用户管理的线程上运行。为了跟踪每个IJob
的进度,我在每个作业中使用一个IProgressObserver
实现观察者模式。当我想报告总体进展时,困难就出现了。
我的理想是有IProgressOverserver.ReportProgress(float jobProgress, float overallProgress
报告工作和总体进展。IJobMaker
可以知道每个工作在整体工作中的部分,并以某种方式收集每个人的报告。
出现了两个主要问题:
-
同步机制?例如,在
IJobMaker
中保留互斥锁可能会损害性能,因为IProgressOverserver.ReportProgress
会被调用很多次,而互斥锁可能会导致上下文切换等等。InterlockedIncrement看起来是一个不错的选择,但由于没有这样的浮点函数,我将被迫以整数增量报告进度。(我想远离c++0x功能或Boost) -
设计模式?
IJob
的进展是从其最深层的算法中报告的。我需要每一个这样的报告,既与中央实体进行总体进度计算,又调用IProgressObserver.ReportProgress
方法,该方法驻留在IJob
中。
关于线程的几个建议:
- 不要报告每一个微小的进展。只有当某个预定义的进度量已经完成,或者某个预定义的时间量已经过去,或者子作业已经完成时,才向主线程报告。这可以大大减少同步的数量。
- 如果你实现了#1,互斥锁可能会工作得很好。
- 如果互斥量太昂贵,你可以使用原子整数变量报告进度:简单地将值从"no progress"缩放到"all done"到
0
…INT_MAX
。
就设计API而言,想出一些合理的东西应该不会太难。我的建议是不要过度设计。
首先,在这种情况下使用浮点数是非常糟糕的做法。使用整数
还有一个建议。你可以使用分段——通过一个互斥锁/原子(一个段)只同步几个线程。然后在所有段中收集总数
此外,还有一个很好的地方可以开始研究高度并行的算法:http://www.1024cores.net/home/lock-free-algorithms
UDPATE 下面是float
的问题示例#include <iostream>
using namespace std;
int main() {
float f = 0;
for(int i=0; i<100000-98; ++i)
{
f += 0.00001;
}
cout << f << endl;
}
因此,如果您有100个作业,每个作业有1000个步骤,那么您将在98年得到1.0的结果,比您预期的要早。
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 是否有可以处理方法调用依赖关系的设计模式?
- 多线程任务总体进度报告的设计模式