C++ 多线程任务总体进度报告的设计模式
我有一个带有C++ 多线程任务总体进度报告的设计模式,c++,multithreading,design-patterns,C++,Multithreading,Design Patterns,我有一个带有IJobMaker实体的库,它创建了一定数量的IJob对象,这些对象将在用户管理的线程上运行。 为了跟踪每个IJob的进度,我在每个作业中使用IProgressObserver实现了observer模式。当我想报告总体进展时,困难就出现了 对我来说,理想的做法是让IProgressOverserver.ReportProgress(float jobProgress,float overallProgress同时报告作业和总体进度。IJobMaker可以了解每个作业在总体工作中的部分
IJobMaker
实体的库,它创建了一定数量的IJob
对象,这些对象将在用户管理的线程上运行。
为了跟踪每个IJob
的进度,我在每个作业中使用IProgressObserver
实现了observer模式。当我想报告总体进展时,困难就出现了
对我来说,理想的做法是让IProgressOverserver.ReportProgress(float jobProgress,float overallProgress
同时报告作业和总体进度。IJobMaker
可以了解每个作业在总体工作中的部分,并以某种方式收集每个人的报告
出现了两个主要问题:
IJobMaker
中保留一个互斥体可能会损害性能,因为IProgressOverserver.ReportProgress
会被多次调用,互斥体可能会引发上下文切换等等。InterlockedIncrement看起来是一个不错的选择,但由于没有用于浮点的此类函数,因此我不会uld将被迫以整数增量报告进度。(我希望远离c++0x功能或Boost)IJob
的进度是从其最深层的算法中报告的。我需要每个这样的报告都与一个中心实体通信以进行总体进度计算,并调用IJob
中的IProgressObserver.ReportProgress
方法关于线程前端的几点建议:
0
。INT\u MAX
就设计API而言,想出合理的方法应该不会太困难。我的一般建议是不要过度设计它。首先,在这种情况下使用浮点是非常糟糕的做法。使用整数 还有一个建议。您可以使用分段-通过一个互斥/原子(一个段)只同步几个线程。然后在所有段中收集总数 此外,还有一个好地方可以开始研究高度并行的算法: UDPATE 有一个浮点数问题的例子
#include <iostream>
using namespace std;
int main() {
float f = 0;
for(int i=0; i<100000-98; ++i)
{
f += 0.00001;
}
cout << f << endl;
}
#包括
使用名称空间std;
int main(){
浮点数f=0;
对于(int i=0;我正在尽可能地“粗略”地”报告,但我仍然相信使用锁可能会对性能产生不良影响。无论我的报告有多远,我总是可以扩展到足以使锁出现瓶颈的程度。(有大量线程和IJob
s)这个库应该能够扩展到10秒的内核。你能详细说明一下为什么使用浮点数不好吗?另外,我不知道你所说的分段是什么意思。我怎么能只同步几个线程呢?浮点数是为范围广泛的值设计的。我想你的si没有介于1E-200
-1E200
之间的进度范围tuation你可以使用AtomicInteger
并进行精确计算,但我从来没有听说过AtomicFloat
。是的,你可以将几个线程按几个段分组。它允许在单个互斥锁上同步更少的线程。但是,我必须同步这些段才能得到最终答案。如果我允许mo的一些延迟,这可能会起作用一些IJob
会一直进行,直到用户获得总体进度报告。但是,由于我想要立即得到答案,我必须在段内和段间同步,这似乎同样有害。关于浮动,我可以让范围介于0和1之间。整数的范围也很广,但只使用了一个子范围。好的,你说得对。在这种情况下,最好的解决方案是原子整数,我想,因为它不作为互斥对象进行系统调用。我不了解这个范围。只需使用一个整数范围,例如0到10亿之间,它将比相同大小的浮点数类型提供更好的精度。否则,您可能会面临一个问题,然后0.01+…百倍..+0.01!=1