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

问题描述 投票:0回答:1

我有一个M图像矢量,必须由最多N个线程并行处理,其中N是用户设置的参数。

我还有一个N Detector实例的向量来处理处理,但每个实例必须在它自己的线程中运行(即,如果两个线程在前一个调用结束之前在同一个实例上调用detect(),则会发生错误的事情)。

Detector是一个独立的类(我可以根据需要修改)我用一个void Detector::detect(cv::Mat image)方法调用,在(冗长的)检测过程的持续时间内改变检测器的内部状态(因此需要防止detect()的并行调用不同的线程)。

我最初用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映射到特定线程的Detector的等价物:

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

如何确保一个线程始终使用探测器池中的相同实例?或者,如果这是错误的方法,我如何将detect()的执行映射到我已经拥有的探测器池上?

c++ ppl
1个回答
0
投票

根据@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
© www.soinside.com 2019 - 2024. All rights reserved.