我有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()
的执行情况?
答案 0 :(得分: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