如果一个线程可用,我如何在一个单独的线程上运行一个函数,假设我总是希望 k 线程在任何时候同时运行?
这是一个伪代码
{{1}}
总之,一旦线程完成,它会通知其他线程,其他任何线程都可以使用其他线程可用的线程。我希望描述清楚。
答案 0 :(得分:0)
我的个人方法:只需做创建k个线程,让他们反复调用foo。你需要一些计数器,防止竞争条件,每次在任何线程调用foo之前递减。一旦执行了所需的调用次数,线程将一个接一个地退出(不完整/伪代码):
unsigned int global_counter = n;
void fooRunner()
{
for(;;)
{
{
std::lock_guard g(global_counter_mutex);
if(global_counter == 0)
break;
--global_counter;
}
foo();
}
}
void runThreads(unsigned int n, unsigned int k)
{
global_counter = n;
std::vector<std::thread> threads(std::min(n, k - 1));
// k - 1: current thread can be reused, too...
// (provided it has no other tasks to perform)
for(auto& t : threads)
{
t = std::thread(&fooRunner);
}
fooRunner();
for(auto& t : threads)
{
t.join();
}
}
如果您要将数据传递给foo
函数,而不是计数器,则可以使用e。 g FIFO或LIFO队列,无论出现哪种最适合给定的用例。一旦缓冲区变空,线程就会退出;但是,你必须提前阻止缓冲区空转,例如,e。 G。通过在启动线程之前预先填充要处理的所有数据。
变体可能是两者的组合:退出,如果全局计数器变为0,则等待队列接收新数据e。 G。否则,通过条件变量,并且主线程在线程已经运行时连续填充队列...
答案 1 :(得分:0)
你可以使用(std::thread in <thread>
)和锁来做你想做的事情,但在我看来你的代码可以简单地使用这样的openmp变成并行。
#pragma omp parallel num_threads(k)
#pragma omp for
for (unsigned i = 0; i < N; ++i)
{
auto t_id = omp_get_thread_num();
if (t_id < K)
foo()
else
other_foo()
}