C + + 11:std ::线程池?
在C ++ 03中,我使用了一个自build线程池的pthread,这个线程池始终保持着一些线程的运行(因为pthread_create
比较慢),这样我就可以在不考虑性能问题的情况下为小任务启动线程。
现在,在C ++ 11中,我们有std::thread
。 我想标准没有说具体的实现,所以我的问题是关于标准库的实现。 他们通常select一个合并的方法构buildstd::thread
是便宜的(例如,不会在posix上调用pthread_create
),或者将std::thread
只是一个包装?
换句话说,在C ++ 11中仍然推荐使用线程池,还是只需要创build一个std::thread
并将性能提高到标准库?
通常, std::thread
应该是底层系统原语的最小包装。 例如,如果你在pthread
平台上,你可以使用下面的程序来testing,不pipe你创build了多less个线程,它们都是用唯一的pthread_t
ID创build的(这意味着它们是在运行中创build的,而不是从线程池):
#include <assert.h> #include <mutex> #include <set> #include <thread> #include <vector> #include <pthread.h> int main() { std::vector<std::thread> workers; std::set<long long> thread_ids; std::mutex m; const int n = 1024; for (int i = 0; i < n; ++i) { workers.push_back(std::thread([&] { std::lock_guard<std::mutex> lock(m); thread_ids.insert(pthread_self()); })); } for (auto& worker : workers) { worker.join(); } assert(thread_ids.size() == n); return 0; }
所以线程池仍然非常有意义。 也就是说,我已经看过一个C ++委员会成员讨论std::async
(IIRC)的线程池的video,但现在我找不到它了。
一个std::thread
是一个执行的线程。 期。 它来自哪里,它是如何到达那里,是否有一些“实际”的线程池等,都与标准无关。 只要它像一个线程,它可能是一个std::thread
。
现在, std::thread
是一个真实的操作系统线程,而不是从线程池中取出的东西。 但是C ++ 11在理论上允许将一个std::thread
作为从池中取出的东西来实现。
std::thread
应该在抽象成本方面非常便宜,这是低层次的东西。 据我所知,标准的库实现可能会尽可能地包装底层的操作系统机制,所以你可以假设线程创build的开销是相似的或等价的。
我不知道任何具体的实现,但是从阅读C ++ Concurrency In Action中我可以得到第二手的理解,即标准build议他们使用最有效的方法。 笔者似乎认为,与DIY相比,成本可能会微不足道。
这个库在概念上类似于Boost,所以我想用Boost实现来得出一些结论不会太牵强。
基本上,我不认为你的问题有直接的答案,因为它没有被指定。 虽然听起来我们会更容易看到非常薄的包装实现,但是我不认为库函数如果提供了效率的好处,就不会被限制使用线程池。
首先,正如你所提到的,C ++标准基本上不指定库的实现。 但是C ++标准库的实现者应服从“假设”规则。
例如,这意味着std::thread
构造函数应该像新线程一样创build,无论是基础API的一个精简包装还是诸如线程池的高效实现。 (在这里,“线程”是指在C ++ 11规范中执行的抽象线程 ,而不是具体的操作系统本地线程)
在线程池实现上;
- C ++编译器和库应该正确处理C ++线程特定的资源(即
thread_local
variables),并且它们应该在运行时协同工作。 - 即使满足上述条件,似乎也不可能与OS特定的线程资源(Windows的TLS,pthread的TSS等)合作。
所以,我假设大多数std::thread
实现只是底层线程API的封装。