如果线程可用,如何在单独的线程上运行函数

时间:2018-04-10 11:40:16

标签: c++ multithreading boost-thread

如果一个线程可用,我如何在一个单独的线程上运行一个函数,假设我总是希望 k 线程在任何时候同时运行?

这是一个伪代码

{{1}}

总之,一旦线程完成,它会通知其他线程,其他任何线程都可以使用其他线程可用的线程。我希望描述清楚。

2 个答案:

答案 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()
}