如何使用boost::thread创建线程池

how to make a threadpool with boost::thread

本文关键字:线程 创建 thread boost 何使用      更新时间:2023-10-16

boost::thread非线程,当调用传递给它的ftor时会创建new thread,当ftor返回时线程退出。

我们使用线程池来最大限度地减少线程创建和销毁成本。但是当提供的ftor返回时,线程池中的每个线程也会被破坏。

那么,构建线程池背后的基本概念是什么呢?有什么永久线程可以为该线程分配ftor吗?

线程池只是一堆已经在运行的线程,它们都在运行相同的函数。这个函数基本上只是在队列上等待,当队列中有"函数"时,它会提取并执行它

伪代码:

void thread_pool_function()
{
    while (true)
    {
        wait_for_signal_that_queue_is_not_empty();
        function_to_call = queue.remove_top();
        unklock_queue_semaphore();
        function_to_call();
    }
}
create_thread(thread_pool_function);
create_thread(thread_pool_function);
create_thread(thread_pool_function);
create_thread(thread_pool_function);

在上面的"代码"中,现在有四个线程,它们最初都在等待将某个东西放入"队列"中。当队列中有东西时,它会提取它,并将其作为函数调用。

这可能是实现线程池的最简单方法。

除了@Joachim发布的内容:

流控制这样一个系统的一种方法(也是我经常使用的一种)是使用任务的"池队列"(阻塞生产者-消费者队列),在启动时创建并填充固定数量的任务对象。任何想要发出任务的线程都必须首先从池中获取任务,并且任务在完成处理后返回到池中。这限制了系统中任务的数量,如果池清空,请求线程只需等待,在空池上被阻塞,直到一些"已用"的任务返回。

这可以很好地工作,提供流控制,防止内存失控,并消除持续的任务创建/销毁。在计时器上定期显示/写入池队列深度也很容易,这样你就可以看到你的应用程序有多"忙"(并检测任何泄漏:)。

编辑:此外,它还消除了系统中任何有界队列的需要。无边界队列更简单,并且往往需要更少的系统调用。