47

C ++ 03では、常に2つのスレッドを実行し続ける自己構築スレッドプールでpthreadを使用しました(pthread_create遅いため)。このようにして、パフォーマンスの問題を気にせずに小さなタスクのスレッドを起動できました。

現在、C++11にはがありstd::threadます。標準は特定の実装について何も述べていないので、私の質問は標準ライブラリの実装についてです。std::thread彼らは一般的に、 sの構築が安価である(そして例えばpthread_createposixを必要としない)プールされたアプローチを選択していますか、それともstd::thread単なるラッパーになりますか?

言い換えれば、スレッドプールはC ++ 11でも推奨されていますか、それとも必要std::threadなときにいつでもスレッドプールを作成して、パフォーマンスを標準ライブラリに任せる必要がありますか?

4

4 に答える 4

32

一般に、std::thread基礎となるシステムプリミティブの最小限のラッパーである必要があります。たとえば、pthreadプラットフォームを使用している場合は、次のプログラムを使用して、作成するスレッドの数に関係なく、すべてが一意のpthread_tIDで作成されることをテストできます(つまり、スレッドプールから借用されたのではなく、オンザフライで作成されます) )::

#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)に関してスレッドプールについて話し合っているビデオを見たことがありますが、今は見つかりません。

于 2012-10-20T23:36:54.557 に答える
14

Astd::threadは実行のスレッドです。限目。それがどこから来たのか、どのようにそこに到達したのか、「実際の」スレッドのプールがあるかどうかなどは、すべて標準とは無関係です。スレッドのように機能する限り、それはである可能性がありstd::threadます。

さて、std::threadスレッドプールなどから引き出されたものではなく、実際のOSスレッドである可能性は高いです。しかし、C ++ 11では、理論的にはstd::thread、プールから取得したものとして実装することができます。

于 2012-10-21T00:38:57.463 に答える
5

std::thread抽象化コストの点で非常に安くなるはずですが、それは低レベルのものです。私が理解しているように、標準ライブラリの実装は、おそらく、基盤となるOSメカニズムを可能な限り厳密にラップするため、スレッド作成のオーバーヘッドは類似または同等であると想定できます。

特定の実装についてはわかりませんが、C ++ Concurrency In Actionを読んだことから、標準では実用的な最も効率的な方法を使用することが提案されていることがわかりました。著者は確かに、DIYと比較してコストは多かれ少なかれ無視できると考えているようでした。

ライブラリは概念的にはBoostに似ているので、Boostの実装を使用していくつかの結論を導き出すことは、それほど大げさではないと思います。

基本的に、質問は特定されていないため、直接答えはないと思います。非常に薄いラッパーの実装が見られる可能性が高いように思われますが、効率が向上する場合は、ライブラリの作成者がスレッドプールの使用を制限されているとは思いません。

于 2012-10-20T23:15:31.843 に答える
2

まず、あなたが言ったように、C++標準は基本的にライブラリの実装を指定していません。ただし、C ++標準ライブラリの実装者は、「あたかも」の規則に従う必要があります。

たとえば、のコンストラクターは、基盤となるAPIのシンラッパーであろうと、スレッドプールなどの効率的な実装であろうと、新しいスレッドが作成されたかのようにstd::thread動作することを意味します。(ここで、「スレッド」は、具体的なOSネイティブスレッドではなく、C ++ 11仕様で実行される抽象的なスレッドを意味します)

スレッドプールの実装について。

  • C ++コンパイラとライブラリは、C ++スレッド固有のリソース(つまりthread_local、変数)を適切に処理する必要があり、実行時に協調して動作する必要があります。
  • 上記の条件が満たされている場合でも、OS固有のスレッドリソース(Windowsの場合はTLS、pthreadの場合はTSSなど)と連携することは不可能のようです。

したがって、ほとんどのstd::thread実装は、基盤となるスレッドAPIの単なるラッパーであると思います。

于 2012-10-23T11:25:31.253 に答える