web-dev-qa-db-ja.com

boost :: threadとboost :: mutexをc ++ 11の同等のものに置き換えるのは賢明ですか?

動機:私がそれを検討している理由は、私の天才プロジェクトマネージャーがブーストは別の依存関係であり、「あなたはそれに依存している」ために恐ろしいと思うからです(ブーストの品質を説明しようとして、しばらくしてあきらめました:( )。私がやりたい小さな理由は、人々がコードを書き始めるので、c ++ 11の機能を学びたいということです。

  1. #include<thread> #include<mutex>とboostの同等物の間に1:1のマッピングはありますか?
  2. Boostをc ++ 11に置き換えることをお勧めしますか?
    もの。私の使用法は原始的ですが、stdがboostの機能を提供しない例はありますか?または(冒s)その逆ですか?

追伸GCCを使用しているので、ヘッダーがあります。

149
NoSenseEtAl

Boost.ThreadとC++ 11標準スレッドライブラリにはいくつかの違いがあります。

  • Boostはスレッドキャンセルをサポートしていますが、C++ 11スレッドはサポートしていません
  • C++ 11は_std::async_をサポートしますが、Boostはサポートしません
  • Boostには、マルチリーダー/シングルライターロック用の_boost::shared_mutex_があります。類似の_std::shared_timed_mutex_は、C++ 14( N3891 )以降でのみ使用できますが、_std::shared_mutex_はC++ 17( N4508 )以降でのみ使用可能です。
  • C++ 11のタイムアウトは、Boostのタイムアウトとは異なります(ただし、Boost.Chronoはすぐに変更される予定です)。
  • 一部の名前が異なります(例:_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 などのサードパーティの実装を取得できる場合がありますが、これは依然として依存関係です。

186

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::mutexstd::mutexの間に大きな違いは見つかりませんでした。

23
Alex B

エンタープライズケース

中規模から多種多様なオペレーティングシステムで実行する必要があり、その結果、それらのオペレーティングシステムでさまざまなコンパイラおよびコンパイラバージョン(特に比較的古いバージョン)でビルドする必要がある企業向けのソフトウェアを作成している場合、今のところC++ 11。つまり、std::threadは使用できないため、boost::threadを使用することをお勧めします。

基本/テックスタートアップケース

1つまたは2つのオペレーティングシステム用に記述している場合は、C++ 11(VS2015、GCC 5.3、Xcode 7など)を主にサポートする最新のコンパイラでのみビルドする必要があることは確かです。ブーストライブラリに依存する場合、std::threadが適切なオプションになる可能性があります。

私の経験

私は個人的には、強化された、頻繁に使用される、互換性が高く、非常に現代的な代替品に対するブーストなどの一貫性のあるライブラリに賛成です。これは、スレッド化などの複雑なプログラミングの主題に特に当てはまります。また、膨大な数の環境、コンパイラ、スレッドモデルなどでboost::thread(および一般的にはブースト)で長い間大きな成功を収めてきました。私の選択でブーストを選択します。

6
Nicholas Smith

std::threadに移行しない理由が1つあります。

静的リンクを使用している場合、std::threadは次のgccのバグ/機能により使用できなくなります。

つまり、std::thread::detachまたはstd::thread::joinを呼び出すと、例外またはクラッシュが発生しますが、これらの場合はboost::threadが正常に機能します。

6
ks1322

Visual Studio 2013では、std::mutexは、boost::mutex、これはいくつかの問題を引き起こしました( この質問 を参照)。

3
Robert Hegner

C++ 17で追加されたstd :: shared_mutexに関して

ここでの他の回答は、一般的な違いの非常に良い概要を提供します。ただし、std::shared_mutexには、ブーストが解決するいくつかの問題があります。

  1. アップグレード可能なミューティック。これらはstd::threadにはありません。リーダーをライターにアップグレードすることができます。他のライターがあなたの前に入ることはできません。これらを使用すると、読み取りモードで大規模な計算の前処理(データ構造のインデックス再作成など)を行い、書き込みにアップグレードして、短時間だけ書き込みロックを保持しながら再インデックスを適用できます。

  2. 公平さ。 std::shared_mutexを使用した一定の読み取りアクティビティがある場合、ライターは無期限にソフトロックされます。これは、別のリーダーが来た場合、常に優先されるためです。 boost:shared_mutexを使用すると、すべてのスレッドが最終的に優先されます。(1) 読者も作家も飢えません。

これのtl; drは、ダウンタイムがなく競合が非常に多い非常に高スループットのシステムがある場合、std::shared_mutexはその上に手動で優先システムを構築しないと機能しません。 boost::shared_mutexはそのまま使用できますが、特定の場合には調整する必要があるかもしれません。 std::shared_mutexの動作は、それを使用するほとんどのコードで発生するのを待っている潜在的なバグであると主張します。

(1)使用する実際のアルゴリズム は、OSスレッドスケジューラに基づいています。私の経験では、読み取りが飽和状態になると、OSX/LinuxよりもWindowsの方が(書き込みロックを取得する際の)停止時間が長くなります。

1
Robert Fraser

Boostの代わりにstdのshared_ptrを使用しようとしましたが、実際にこのクラスのgcc実装にバグが見つかりました。デストラクタが2回呼び出されたため、アプリケーションがクラッシュしました(このクラスはスレッドセーフである必要があり、このような問題は発生しません)。 boost :: shared_ptrに移行した後、すべての問題が消えました。 C++ 11の現在の実装はまだ成熟していません。

Boostにはさらに多くの機能があります。たとえば、標準バージョンのヘッダーは、ストリームにシリアライザーを提供しません(つまり、cout << duration)。 Boostには、独自の等を使用する多くのライブラリがありますが、stdバージョンとは連携しません。

要約すると、boostを使用してアプリケーションを既に作成している場合は、C++ 11標準に移行するための努力をするよりも、コードをそのままにしておく方が安全です。

0
user3323559