.NETチームがInterlocked.Exchange操作でブール値をサポートしないことを決定した実用的な理由はありますか?なぜInterlocked.Exchangeはブール型をサポートしていませんか?
使用例の1つは、一部のコードが一度だけ実行されることを保証し、そのためにブール値フラグを使用する場合です。
.NETチームがInterlocked.Exchange操作でブール値をサポートしないことを決定した実用的な理由はありますか?なぜInterlocked.Exchangeはブール型をサポートしていませんか?
使用例の1つは、一部のコードが一度だけ実行されることを保証し、そのためにブール値フラグを使用する場合です。
はい、正当な理由があります。 Interlockedメソッドの実装には、プロセッサレベルでの低レベルサポートが必要です。たとえば、this answerを参照してください。これはアーキテクチャに依存しないフレームワークを定義するときの問題です。
ネイティブプロセッサのワードサイズの一部であるデータ型でInterlockedクラスでサポートされるローロック手法を実装することは困難です。 10年以上前に普及していたCPU設計に対するRISCのアプローチは、それを強く落胆させました。オペランドサイズとネイティブメモリバス幅の不一致により、実装が非常に難しくなります。インテルのx86アーキテクチャーがまだあなたの膝に残っている理由の1つは、ショートカットを使用しないことですでに30年生き残っていることです。このwikipedia articleにRISCの背景情報があります。
IOWを使用することができます。インターロックドエクスチェンジは、32-ビットとboolの過負荷の欠如は、これの単なる結果です。 –
4バイト未満で動作するCAS命令はないため、ブール(1バイト)で動作するInterlocked.Exchangeのオーバーロードは、他のオーバーロードと同じコストで実装することは不可能です。私はフレームワークのデザイナーが混乱を避けたいと思っています。 –
.NETブール値はアンダーネース32ビットです。インターロック操作では、Int32と同じCPU命令を使用できます。 – Dennis
質問に答えることはできませんが、回避策として、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回だけであり、最初は多くないと仮定します)。
もちろんintとif(Interlocked.CompareExchange(ref value、1、0)== 0){...} 'を使うこともできます。 ..またはおそらくもっと簡単に - 'Lazy':http://msdn.microsoft.com/en-us/library/dd642331.aspx –
良い質問ですが、これは長年何度もマイクロソフトに報告されています。私は、それが見落とされている以外に、満足のいく理由を自分で見たことはありません。誰かが何かを知っているなら私たちに知らせてください! –
ブーリアンのインターロックサポートが必要な場合は、InterlockedBoolean.cs(https://gist.github.com/hanswolff/7926751)の実装 – quadfinity