2009-08-10 5 views
4

Windowsでは、イベント(SetEventWaitForSingleObject)、ミューテックス、クリティカルセクションなど、スレッドを同期するのに便利なオブジェクトが多数用意されています。なぜライブラリはウィンドウに独自の基本ロックを実装していますか?

個人的には、私は彼らが特にロックされていない限り、非常に少ないオーバーヘッドが発生することは確かです。しかし、ブーストのような数々のライブラリを見ると、Windows上でインターロックされたメソッドを使用して独自のロックを実装するのに多くの手間がかかります。

人々がロックレスキューとな、ザッツ以来、専門的なケースを記述し、なぜ私が理解することができますが、人々は、基本的な同期オブジェクトの独自のバージョンを実装することを選択した理由はどのような理由があるのでしょうか?

答えて

14

ライブラリは、独自のロックを実装していません。これは、OSのサポートなしではほとんど不可能です。

ここでは、です。単にOSが提供するロック機構をラップするだけです。

ブーストは理由のカップルのためにそれをしない:

  • 彼らはC++の機能を活用して、より良い設計されたロックAPIを提供することができます。 Windows APIはCのみであり、あまりうまく設計されていないCです。
  • 彼らはある程度の移植性を提供することができます。 LinuxマシンやMacでアプリケーションを実行する場合、同じBoost APIを使用することができます。 Windows独自のAPIは明らかにWindows固有です。
  • Windowsで提供されているメカニズムには、明らかに不利な点があります。windows.hを含める必要があります。これは、大量のマクロ濫用による大域ネームスペースの汚染ではありません。
+0

boost \ thread \ win32 \ basic_timed_mutex.hppを見てください私はwin32スレッドオブジェクトの使用を見ません。とにかくアトミックな特殊なCPU命令を使用するインターロックされたメソッドで実行されているようです。 –

+2

インターロックされたメソッドは、いくつかのWin32同期オブジェクトの基礎でもあります。これはmutexesやselectのために本当に必要なものです。 – Blindy

+0

インターロックされたメソッドはWin32 APIの一部です。それらは上位レベルのWin32同期オブジェクトより移植性がありません。 – jalf

4

私が考えることができる1つの特別な理由は、移植性です。 Windowsのロックは自分では問題ありませんが、他のプラットフォームには移植できません。ポータブルであることを望むライブラリは、プラットフォーム間で同じセマンティクスを保証するために、独自のロックを実装する必要があります。

+0

基本的には、インターロックされたメソッドを使用してWindowsコードを拡張するのは基本的にはpthreads他のプラットフォーム? –

+0

@ファイアランサーはい、私は**推測している**その場合です – JaredPar

1

ライブラリのロックコードを書くことは、そのライブラリがクロスプラットフォームを対象としている場合に便利です。ライブラリのユーザは、ライブラリのロック機能を使用することができ、基本となるプラットフォームの実装を気にする必要はありません。ライブラリにターゲットとされているすべてのプラットフォームのバージョンがあると仮定すると、移植する必要があるコードは1つ少なくなります。

+0

JaredParは同じ答えを投稿しました –

2
  1. 多くのライブラリ(別名ブースト)では、corssプラットフォームコードを記述する必要があります。したがって、WaitForSingleObjectとSetEventを使用することはできません。また、Monitors、Win32 APIが逃している条件などの一般的なイディオムもあります(ただし、これらの基本プリミティブを使用して実装できます)
  2. 原子カウンタのようなロックフリーのデータ構造は非常に便利です。 boost::shared_ptrは、クリティカルセクションのオーバーヘッドなしでスレッドを安全にするためにそれらを使用します。ほとんどのコンパイラ(msvcではなく)はスレッドセーフなコピーオンライトを実装するためにアトミックカウンタを使用しますstd::string
  3. キューのようなものは、スレッドセーフな方法で非常に効率的に実装することができます。ロックなしでは、特定のアプリケーションでパフォーマンスが大幅に向上する可能性があります。
2

Windows OS同期オブジェクトを使用しない独自のロックを実装する理由がよくあることがあります。しかしそうすることは「鋭いスティック」です。

例:ハードウェアコンテキストと同じ数のスレッドを実行していることがわかっている場合、待機しているスレッドの1つをスリープ状態にするまでの待ち時間ロックが非常に重要な場合は、ユーザー空間に完全に実装されたスピンロックを選択することができます。待機中のスレッドがロックを回している唯一のスレッドであれば、それを所有するスレッドから待機中のスレッド同じ状況下でOSロックを持つスレッドに通知するレイテンシよりも速いオーダーのスレッドに、キャッシュラインをオーナースレッドに移動して待機スレッドに戻すレイテンシです。

しかし、これをやりたいのはかなり狭いですハードウェアスレッドよりも多くのソフトウェアスレッドを持つようになると、後悔する可能性があります。このシナリオでは、スピンロックを回すだけで、OS全体をスケジューリングすることができます。また、電力を気にすると、スピンロックはプロセッサが低電力状態にならないために悪いことです。

私は移植性の議論を買うか分からない。ポータブルライブラリには、同期のためにさまざまなOS APIを抽象化するOS移植性レイヤーがあることがよくあります。ロックを扱っている場合、pthread_mutexは、抽象化レイヤの下のWindowsミューテックスまたはクリティカルセクションと意味的に同じにすることができます。ここにはいくつかの例外がありますが、ほとんどの人にとってこれは真です。 WindowsイベントやPOSIX条件変数を扱っているのであれば、それらは抽象的に扱いにくいものです。 (VistaはPOSIXスタイルの条件変数を導入しましたが、多くのWindowsソフトウェア開発者はVistaを必要とする立場にありません...)

関連する問題