Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多线程任务总体进度报告的设计模式_C++_Multithreading_Design Patterns - Fatal编程技术网

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
    方法


  • 关于线程前端的几点建议:

  • 不要报告每一个微小的进度。只有在完成某个预定义的进度、某个预定义的时间或子作业完成后,才向主线程报告。这可以大大减少同步量
  • 如果实现#1,互斥锁可能工作得很好
  • 如果互斥锁过于昂贵,您可以使用原子整数变量报告进度:只需将值从“无进度”缩放到“全部完成”,再缩放到
    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