C++ 03では、常にいくつかのスレッドを実行し続ける自己構築のスレッドプールでpthreadを使用しました(pthread_create
が遅いため)。このようにして、パフォーマンスの問題を考えずに小さなタスクのスレッドを起動できました。 。
現在、C++ 11にはstd::thread
があります。標準では特定の実装について何も言われていないので、私の質問は標準ライブラリの実装に関するものです。彼らは一般に、std::thread
sの構築が安価な(そして、たとえばposixでpthread_create
を呼び出さない)プールされたアプローチを選択していますか、それともstd::thread
は単なるラッパーですか?
つまり、スレッドプールはC++ 11でも引き続き推奨されますか、それとも必要に応じてstd::thread
を作成し、パフォーマンスを標準ライブラリに任せる必要がありますか?
一般的に、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;
}
したがって、スレッドプールは依然として完全に意味をなします。そうは言っても、C++委員会のメンバーがstd::async
(IIRC)に関してスレッドプールについて議論したビデオを見たことがありますが、今のところ見つけることができません。
std::thread
は実行のスレッドです。限目。それがどこから来て、どのようにそこに到達するか、「実際の」スレッドのプールがあるかどうかなどは、すべて標準とは無関係です。スレッドのように動作する限り、std::thread
。
今、std::thread
は、実際のOSスレッドであり、スレッドプールなどから引き出されたものではありません。ただし、C++ 11では理論的にstd::thread
プールから引き出されたものとして実装されます。
std::thread
は、抽象化コストの点で非常に安価であると考えられています。低レベルのものです。私が理解しているように、標準ライブラリの実装はおそらく、基礎となるOSメカニズムをできるだけ密接にラップするため、スレッド作成のオーバーヘッドが類似または同等であると想定できます。
私は特定の実装については知りませんが、C++ Concurrency In Actionを読むことからの私の間接的な理解は、標準がそれらが最も効率的な方法を実用的に使用することを示唆していることです。著者は確かに、DIYに比べてコストは多かれ少なかれ無視できると考えているように見えました。
ライブラリは概念的にBoostに似ているので、Boost実装を使用して結論を出すことは、それほど大げさなことではないと思います。
基本的に、指定されていないため、質問に対する直接的な回答はないと思います。非常に薄いラッパーの実装を目にする可能性が高くなるように思えますが、ライブラリライターが効率の向上を提供する場合、スレッドプールの使用は制限されないと思います。
最初に、あなたが述べたように、C++標準は基本的にライブラリの実装を指定していません。しかし、C++標準ライブラリshallの実装者は、「as-if」ルールに従います。
たとえば、std::thread
振る舞うif基になるAPIのシンラッパーまたはthread-poolなどの効率的な実装の場合、新しいスレッドが作成されます。 (ここで、「スレッド」は、具体的なOSネイティブスレッドではなく、C++ 11仕様の抽象実行スレッドを意味します)
スレッドプールの実装。
thread_local
変数)、および実行時に連携して連携する必要があります。したがって、ほとんどのstd::thread
実装は、基礎となるスレッドAPIの単なるラッパーです。