動機:私がそれを検討している理由は、私の天才プロジェクトマネージャーがブーストは別の依存関係であり、「あなたはそれに依存している」ために恐ろしいと思うからです(ブーストの品質を説明しようとして、しばらくしてあきらめました:( )。私がやりたい小さな理由は、人々がコードを書き始めるので、c ++ 11の機能を学びたいということです。
#include<thread> #include<mutex>
とboostの同等物の間に1:1のマッピングはありますか?追伸GCCを使用しているので、ヘッダーがあります。
Boost.ThreadとC++ 11標準スレッドライブラリにはいくつかの違いがあります。
std::async
_をサポートしますが、Boostはサポートしませんboost::shared_mutex
_があります。類似の_std::shared_timed_mutex
_は、C++ 14( N3891 )以降でのみ使用できますが、_std::shared_mutex
_はC++ 17( N4508 )以降でのみ使用可能です。boost::unique_future
_ vs _std::future
_)std::thread
_の引数渡しのセマンティクスは_boost::thread
_とは異なります--- Boostはコピー可能な引数を必要とする_boost::bind
_を使用します。 _std::thread
_を使用すると、_std::unique_ptr
_などの移動専用タイプを引数として渡すことができます。 _boost::bind
_を使用するため、ネストされたバインド式の__1
_などのプレースホルダーのセマンティクスも異なる場合があります。join()
またはdetach()
を明示的に呼び出さない場合、_boost::thread
_デストラクタおよび割り当て演算子は、破棄/割り当て中のスレッドオブジェクトでdetach()
を呼び出します。に。 C++ 11 _std::thread
_オブジェクトでは、これによりstd::terminate()
が呼び出され、アプリケーションが中止されます。移動のみのパラメーターに関するポイントを明確にするために、以下は有効なC++ 11であり、int
の所有権を一時_std::unique_ptr
_から_f1
_のパラメーターに転送します。新しいスレッドが開始されます。ただし、_boost::thread
_を使用すると、_boost::bind
_を内部で使用し、_std::unique_ptr
_をコピーできないため、機能しません。 GCCで提供されるC++ 11スレッドライブラリにもバグがあり、この実装も_std::bind
_を使用するため、この動作を妨げます。
_void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));
_
Boostを使用している場合、コンパイラがサポートしていれば、おそらくC++ 11スレッドに比較的簡単に切り替えることができます(たとえば、Linux上のGCCの最新バージョンでは、_-std=c++0x
_モード)。
コンパイラがC++ 11スレッドをサポートしていない場合、 Just :: Thread などのサードパーティの実装を取得できる場合がありますが、これは依然として依存関係です。
std::thread
は、主にboost::thread
をモデルにしており、 いくつかの違い を使用しています。
- boostのコピー不可能な、1つのハンドルマップから1つのOSスレッドへのセマンティクスは保持されます。ただし、このスレッドは移動可能で、ファクトリー関数からスレッドを返し、コンテナーに配置できます。
- この提案は、
boost::thread
にキャンセルを追加しますが、これは重大な問題です。この変更は、スレッドだけでなく、C++スレッドライブラリの残りにも大きな影響を与えます。この大きな変化は、利益のために正当化されると考えられています。
- スレッドデストラクタは、親スレッドがキャンセルされたときに子スレッドが誤ってリークしないように、デタッチする前にキャンセルを呼び出す必要があります。
- キャンセルせずにデタッチを有効にするには、明示的なデタッチメンバーが必要になりました。
- スレッドハンドルとスレッドIDの概念は、2つのクラスに分けられています(これらは
boost::thread
の同じクラスです)。これは、スレッドIDの簡単な操作と保存をサポートするためです。- 他のどの結合可能スレッドとも等しくないことが保証されるスレッドIDを作成する機能が追加されました(
boost::thread
にはありません)。これは、以前の呼び出しと同じスレッドによって実行されているかどうかを知りたいコードに便利です(再帰的なmutexは具体的な例です)。- 必要に応じてクライアントが基盤のOSを使用してスレッドを操作できるように、ネイティブスレッドハンドルを取得する「バックドア」が存在します。
これは2007年のものであるため、一部のポイントは無効になりました。boost::thread
にはnative_handle
関数があり、コメント者が指摘しているように、std::thread
にはキャンセルがありません。
boost::mutex
とstd::mutex
の間に大きな違いは見つかりませんでした。
エンタープライズケース
中規模から多種多様なオペレーティングシステムで実行する必要があり、その結果、それらのオペレーティングシステムでさまざまなコンパイラおよびコンパイラバージョン(特に比較的古いバージョン)でビルドする必要がある企業向けのソフトウェアを作成している場合、今のところC++ 11。つまり、std::thread
は使用できないため、boost::thread
を使用することをお勧めします。
基本/テックスタートアップケース
1つまたは2つのオペレーティングシステム用に記述している場合は、C++ 11(VS2015、GCC 5.3、Xcode 7など)を主にサポートする最新のコンパイラでのみビルドする必要があることは確かです。ブーストライブラリに依存する場合、std::thread
が適切なオプションになる可能性があります。
私の経験
私は個人的には、強化された、頻繁に使用される、互換性が高く、非常に現代的な代替品に対するブーストなどの一貫性のあるライブラリに賛成です。これは、スレッド化などの複雑なプログラミングの主題に特に当てはまります。また、膨大な数の環境、コンパイラ、スレッドモデルなどでboost::thread
(および一般的にはブースト)で長い間大きな成功を収めてきました。私の選択でブーストを選択します。
std::thread
に移行しない理由が1つあります。
静的リンクを使用している場合、std::thread
は次のgccのバグ/機能により使用できなくなります。
つまり、std::thread::detach
またはstd::thread::join
を呼び出すと、例外またはクラッシュが発生しますが、これらの場合はboost::thread
が正常に機能します。
Visual Studio 2013では、std::mutex
は、boost::mutex
、これはいくつかの問題を引き起こしました( この質問 を参照)。
ここでの他の回答は、一般的な違いの非常に良い概要を提供します。ただし、std::shared_mutex
には、ブーストが解決するいくつかの問題があります。
アップグレード可能なミューティック。これらはstd::thread
にはありません。リーダーをライターにアップグレードすることができます。他のライターがあなたの前に入ることはできません。これらを使用すると、読み取りモードで大規模な計算の前処理(データ構造のインデックス再作成など)を行い、書き込みにアップグレードして、短時間だけ書き込みロックを保持しながら再インデックスを適用できます。
公平さ。 std::shared_mutex
を使用した一定の読み取りアクティビティがある場合、ライターは無期限にソフトロックされます。これは、別のリーダーが来た場合、常に優先されるためです。 boost:shared_mutex
を使用すると、すべてのスレッドが最終的に優先されます。(1) 読者も作家も飢えません。
これのtl; drは、ダウンタイムがなく競合が非常に多い非常に高スループットのシステムがある場合、std::shared_mutex
はその上に手動で優先システムを構築しないと機能しません。 boost::shared_mutex
はそのまま使用できますが、特定の場合には調整する必要があるかもしれません。 std::shared_mutex
の動作は、それを使用するほとんどのコードで発生するのを待っている潜在的なバグであると主張します。
(1)使用する実際のアルゴリズム は、OSスレッドスケジューラに基づいています。私の経験では、読み取りが飽和状態になると、OSX/LinuxよりもWindowsの方が(書き込みロックを取得する際の)停止時間が長くなります。
Boostの代わりにstdのshared_ptrを使用しようとしましたが、実際にこのクラスのgcc実装にバグが見つかりました。デストラクタが2回呼び出されたため、アプリケーションがクラッシュしました(このクラスはスレッドセーフである必要があり、このような問題は発生しません)。 boost :: shared_ptrに移行した後、すべての問題が消えました。 C++ 11の現在の実装はまだ成熟していません。
Boostにはさらに多くの機能があります。たとえば、標準バージョンのヘッダーは、ストリームにシリアライザーを提供しません(つまり、cout << duration)。 Boostには、独自の等を使用する多くのライブラリがありますが、stdバージョンとは連携しません。
要約すると、boostを使用してアプリケーションを既に作成している場合は、C++ 11標準に移行するための努力をするよりも、コードをそのままにしておく方が安全です。