C++11:标准::线程池?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12993451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++11: std::thread pooled?
提问by lucas clemente
In C++03 I used pthread with a self-built thread pool that always kept a couple of threads running (since pthread_create
is slow), this way I was able to launch threads for small tasks without thinking about performance issues.
在 C++03 中,我将 pthread 与自建线程池一起使用,该线程池始终保持几个线程运行(因为pthread_create
速度很慢),这样我就能够为小任务启动线程,而无需考虑性能问题。
Now, in C++11 we have std::thread
. I guess the standard doesn't say anything about the specific implementation, so my question is about the standard library implementations. Are they generally opting for a pooled approach where constructing std::thread
s is cheap (and e.g. doesn't call pthread_create
on posix), or will std::thread
just be a wrapper?
现在,在 C++11 中,我们有std::thread
. 我想标准没有说明具体的实现,所以我的问题是关于标准库的实现。他们通常选择一种池化方法,其中构造std::thread
s 很便宜(例如不调用pthread_create
posix),还是std::thread
只是一个包装器?
In other words, is a thread pool still recommended in C++11, or should I just create a std::thread
whenever I need one and leave performance up to the standard library?
换句话说,在 C++11 中是否仍然推荐使用线程池,还是应该std::thread
在需要时创建一个线程池并将性能留给标准库?
采纳答案by dorserg
Generally, std::thread
should be a minimal wrapper around underlying system primitive. For example, if you're on pthread
platform, you can test with the following program that no matter how many threads you create, they are all created with unique pthread_t
ids (which implies they're created on the fly and not borrowed from a thread pool):
通常,std::thread
应该是底层系统原语的最小包装器。例如,如果您在pthread
平台上,您可以使用以下程序进行测试,无论您创建多少个线程,它们都是使用唯一pthread_t
id创建的(这意味着它们是动态创建的,而不是从线程池中借用的) ):
#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;
}
So thread pools still make perfect sense. That said, I've seen a video where C++ committee members discussed thread pools with regard to std::async
(IIRC), but I can't find it right now.
所以线程池仍然非常有意义。也就是说,我看过一个视频,其中 C++ 委员会成员讨论了关于std::async
(IIRC) 的线程池,但我现在找不到。
回答by Nicol Bolas
A std::thread
is a thread of execution. Period. Where it comes from, how it gets there, whether there is some pool of "actual" threads, etc, is all irrelevant to the standard. As long as it acts like a thread, it could be a std::thread
.
Astd::thread
是一个执行线程。时期。它来自哪里,它如何到达那里,是否有一些“实际”线程池等等,都与标准无关。只要它像一个线程,它就可以是一个std::thread
.
Now, odds are good that std::thread
is a real-life OS thread, not something pulled from a thread pool or whatever. But C++11 does theoretically allow a std::thread
to be implemented as a something pulled from a pool.
现在,很有可能std::thread
是现实生活中的操作系统线程,而不是从线程池或其他任何东西中提取的东西。但是 C++11 理论上确实允许将 astd::thread
实现为从池中提取的东西。
回答by Elliott
std::thread
is supposed to come extremely cheaply in terms of abstraction costs, it's low level stuff. As I understand it, standard library implementations are probably going to just wrap the underlying OS mechanisms as closely as possible so you can assume the overhead of thread creation to be similar or equivalent.
std::thread
就抽象成本而言,它应该非常便宜,它是低级的东西。据我了解,标准库实现可能会尽可能紧密地包装底层操作系统机制,因此您可以假设线程创建的开销是相似或等效的。
I don't know about any specific implementations but it is my secondhand understanding from reading C++ Concurrency In Actionthat the standard suggests they use the most efficient method practical. The author certainly seemed to think the cost would be more or less negligible compared to DIY.
我不知道任何具体的实现,但这是我从阅读C++ Concurrency In Action 的二手理解,标准建议他们使用最有效的方法。笔者似乎当然认为与DIY相比,成本或多或少可以忽略不计。
The library's similar to Boost conceptually so I imagine using the Boost implementation to draw some conclusions wouldn't be too farfetched.
该库在概念上类似于 Boost,所以我想使用 Boost 实现来得出一些结论不会太牵强。
Basically, I don't think there's an answer for your question directly because it just isn't specified. While it sounds to me that we're gonna be more likely to see very thin wrapper implementations, I don't think library writers are restricted from using thread pools if it offers efficiency benefits.
基本上,我认为您的问题没有直接答案,因为它没有具体说明。虽然在我看来我们将更有可能看到非常瘦的包装器实现,但我认为库编写者不会因为线程池提供效率优势而被限制使用它。
回答by yohjp
First, as you mentioned, C++ standard basically doesn't specify library implementation. But an implementer of C++ standard library shallobey the "as-if" rule.
首先,正如您提到的,C++ 标准基本上没有指定库实现。但是 C++ 标准库的实现者应该遵守“as-if”规则。
For instance, it means that constructor of std::thread
shall behave as ifnew thread created whether a thin wrapper of underlying API or an efficient implementation such as thread-pool. (here, 'thread' means an abstract thread of executionin C++11 specification, not a concrete OS native thread)
例如,这意味着无论是底层 API 的瘦包装器还是线程池等高效实现,的构造函数都std::thread
应该像创建新线程一样。(这里,“线程”是指C++11 规范中的抽象执行线程,而不是具体的 OS 本地线程)
On the thread-pool implementation;
关于线程池的实现;
- C++ compiler and library shall properly treat C++ thread specific resources (ie.
thread_local
variable), and they should work together cooperatively at runtime. - Even if above condition has been satisfied, it seems impossible to co-work with OS specific thread resources (TLS for Windows, TSS for pthread, etc.).
- C++ 编译器和库应该正确对待 C++ 线程特定资源(即
thread_local
变量),并且它们应该在运行时协同工作。 - 即使满足上述条件,似乎也不可能与操作系统特定的线程资源(Windows 的 TLS、pthread 的 TSS 等)协同工作。
So, I assume that most std::thread
implementation is just wrapper of the underlying threading API.
因此,我假设大多数std::thread
实现只是底层线程 API 的包装器。