2011-05-28 14 views
47

.NETチームがInterlocked.Exchange操作でブール値をサポートしないことを決定した実用的な理由はありますか?なぜInterlocked.Exchangeはブール型をサポートしていませんか?

使用例の1つは、一部のコードが一度だけ実行されることを保証し、そのためにブール値フラグを使用する場合です。

+3

もちろんintとif(Interlocked.CompareExchange(ref value、1、0)== 0){...} 'を使うこともできます。 ..またはおそらくもっと簡単に - 'Lazy ':http://msdn.microsoft.com/en-us/library/dd642331.aspx –

+0

良い質問ですが、これは長年何度もマイクロソフトに報告されています。私は、それが見落とされている以外に、満足のいく理由を自分で見たことはありません。誰かが何かを知っているなら私たちに知らせてください! –

+0

ブーリアンのインターロックサポートが必要な場合は、InterlockedBoolean.cs(https://gist.github.com/hanswolff/7926751)の実装 – quadfinity

答えて

47

はい、正当な理由があります。 Interlockedメソッドの実装には、プロセッサレベルでの低レベルサポートが必要です。たとえば、this answerを参照してください。これはアーキテクチャに依存しないフレームワークを定義するときの問題です。

ネイティブプロセッサのワードサイズの一部であるデータ型でInterlockedクラスでサポートされるローロック手法を実装することは困難です。 10年以上前に普及していたCPU設計に対するRISCのアプローチは、それを強く落胆させました。オペランドサイズとネイティブメモリバス幅の不一致により、実装が非常に難しくなります。インテルのx86アーキテクチャーがまだあなたの膝に残っている理由の1つは、ショートカットを使用しないことですでに30年生き残っていることです。このwikipedia articleにRISCの背景情報があります。

+14

IOWを使用することができます。インターロックドエクスチェンジは、32-ビットとboolの過負荷の欠如は、これの単なる結果です。 –

+0

4バイト未満で動作するCAS命令はないため、ブール(1バイト)で動作するInterlocked.Exchangeのオーバーロードは、他のオーバーロードと同じコストで実装することは不可能です。私はフレームワークのデザイナーが混乱を避けたいと思っています。 –

+0

.NETブール値はアンダーネース32ビットです。インターロック操作では、Int32と同じCPU命令を使用できます。 – Dennis

8

質問に答えることはできませんが、回避策として、Cのやりかたにboolの代わりにintを使用することができます。

int m_IsFirstTime = 1; // 1 means true 0 means false. 

    void SomeMethod() 
    { 
     if (1 == Interlocked.Exchange(ref m_IsFirstTime , 0)) 
      // Do something for the first time. 

     else 
      // Do something for all other times. 

    } 

P.S. readがwriteよりも速いという証拠がある場合、Interlocked.CompareExchangeはこのケースではより良いかもしれません(最初は1回だけであり、最初は多くないと仮定します)。

関連する問題