2 つのスレッドが「同時に」BOOL を YES に設定するとどうなりますか?
4 に答える
Jackoによって提案されたソリューションのコードは次のとおりです。と
を併用volatile
uint32_t
OSAtomicOr32Barrier
OSAtomicAnd32Barrier
#import <libkern/OSAtomic.h>
volatile uint32_t _IsRunning;
- (BOOL)isRunning {
return _IsRunning != 0;
}
- (void)setIsRunning:(BOOL)allowed {
if (allowed) {
OSAtomicOr32Barrier(1, & _IsRunning); //Atomic bitwise OR of two 32-bit values with barrier
} else {
OSAtomicAnd32Barrier(0, & _IsRunning); //Atomic bitwise AND of two 32-bit values with barrier.
}
}
いいえ。ロック構造がなければ、型変数の読み取り/書き込みは Objective C ではアトミックではありません。
2 つのスレッドが同時に BOOL に YES を書き込むと、どちらが先に入ったかに関係なく、結果は YES になります。
参照してください:スレッド実行の同期
私は受け入れられた答えから逸脱しなければならないでしょう。ごめん。客観的 c は、非アトミックとして宣言された BOOL プロパティが実際にアトミックであることを保証しませんが、最も関心のあるハードウェア (すべての iOS および macos デバイス) には、バイトの読み取りとストアをアトミックに実行する命令があると推測する必要があります。したがって、Apple が 10 ビット バイトを送信する 5 ビット幅のバスを持つ IBM マイクロコントローラーで実行される Road Light OS を発表しない限り、アトミック BOOL が必要な状況で非アトミック BOOL を使用することもできます。コードを Road Light OS に移植することはできませんが、コードの将来性を犠牲にすることができれば、このユース ケースでは非アトミックで問題ありません。強化された個人がいると確信しているため、合成されたBOOLゲッターとセッターをアトミック/非アトミックケースで逆アセンブルして何を確認するかという課題が発生します。違いです。少なくともARMでは。
これからのあなたのポイントはおそらくこれです
- BOOL プロパティをアトミックとして宣言でき、iOS および macOS が本質的にサポートするすべてのハードウェアで 1 セント硬貨の費用がかかりません。
- メモリバリアは原子性と直交しています
- [非常に] ファジーなロジックに興味がない限り、ブール値を格納するために 4 バイト プロパティを使用しないでください。それはばかげていて無駄です。あなたは、float と double を区別できない Java プログラマーのクローンになりたくありませんか?
- BOOL変数(明らかにアトミック/非アトミックデコレーターをサポートしていないものは、一部の狭いバスアーキテクチャではアトミックではありません.目的のCはとにかく使用されません([非常に]マイクロOSの有無にかかわらず、マイクロコントローラーはCとアセンブリの領域であると思います.彼らは通常、objc ランタイムがもたらす荷物は必要ありません)