代码之家  ›  专栏  ›  技术社区  ›  GPhilo satyendra

如何在concurrency::parallel_for中可靠地将线程与对象实例配对?

  •  0
  • GPhilo satyendra  · 技术社区  · 6 年前

    我有一个m个图像的向量,它必须由多达n个线程并行处理,其中n是用户设置的参数。

    我还有一个向量n Detector 负责处理的实例,但每个实例必须在其自己的线程中运行(即,如果两个线程调用 detect() 在上一个调用结束之前的同一个实例上,会发生不好的事情)。

    检测器 是一个独立的类(如果需要,我可以修改它) void Detector::detect(cv::Mat image) 方法I调用,该方法在(长时间的)检测过程期间更改检测器的内部状态(因此需要防止 检测() 从不同的线程)。

    我最初是用openmp实现的:

    #pragma omp parallel for num_threads(N)
    for(int i=0; i<M; i++)
    {
        detectors[omp_get_thread_num()].detect(images[i]);
    }
    

    但是,由于检测会抛出异常,我想使用ppl parallel_for 相反,它在主线程中带有源自线程的异常捕获。

    问题是,我找不到 omp_get_thread_num 我可以用来绘制 检测器 到特定线程:

    concurrency::CurrentScheduler::Create( concurrency::SchedulerPolicy( 2, 
    concurrency::MinConcurrency, 1, concurrency::MaxConcurrency, N ) );
    concurrency::parallel_for(0, M, [&](int i)
    {
        detectors[?????].detect(images[i]);
    });
    concurrency::CurrentScheduler::Detach(); // clear scheduler
    

    如何确保一个线程始终使用来自检测器池的同一实例? 或者,如果这是错误的方法,我如何映射 检测() 我已经有了这么多探测器?

    1 回复  |  直到 6 年前
        1
  •  0
  •   GPhilo satyendra    6 年前

    根据“Nathanoliver”的建议,我最终使用了 concurrent_queue 要解决这个问题:

    using namespace concurrency;
    CurrentScheduler::Create( SchedulerPolicy( 2, 
    MinConcurrency, 1, MaxConcurrency, N ) );
    concurrent_queue<std::shared_ptr<Detector>> detectors_queue;
    for(auto& det : obj->instances)
    {
        detectors_queue.push(det);
    }
    parallel_for(0, M, [&](int i)
    {
        std::shared_ptr<Detector> thread_det = nullptr;
        while(!detectors_queue.try_pop(thread_det))
        {
            wait(100);
        }
        thread_det->detect(images[i]);
        detectors_queue.push(thread_det);
    });
    CurrentScheduler::Detach(); // clear scheduler
    
    推荐文章