何も考えずに@synchronizedを使っていると次第に心が蝕まれていくので、
時にはスピンロックを使いたくなる事があると思います。
幸いな事に自作しなくてもiOSがAPIを提供してくれているので、それを使いましょう。
基本的な使い方を以下のサンプルコードで示します。 ヘッダ名が如何にもリジェクトされそうな雰囲気を醸し出していますが、大丈夫だそうです。
#include <libkern/OSAtomic.h>
static volatile OSSpinLock lock = OS_SPINLOCK_INIT;
void spinlock_lock()
{
OSSpinLockLock(&lock);
}
void spinlock_unlock()
{
OSSpinLockUnlock(&lock);
}これをmutexの代わりに使うだけです。OSSpinLock型の実体はただのint32_tです。
マクロを使って疑似ブロックを作るなら例えば次のようになります。
#define SPINLOCK(lock) for (int ___do = ({ OSSpinLockLock(&(lock)); 1; }); ___do || ({ OSSpinLockUnlock(&(lock)); 0; }); ___do = 0)
...
SPINLOCK(a_lock) {
do_something();
}
...当然ですが、スピンロック一般の注意点として
- ロックされる時間が極めて短いこと
- 中でコンテキストスイッチが起きない事
- 再帰ロックしないこと
等を考慮して使う必要が有ります。特に2はシングルコアで致命傷を負う事にもなるので要注意です。
かなり過激に使わない限りパフォーマンスは@synchronizedとさほど変わらなかったりするので、
必ず計測してから導入する事をお勧めします。
http://www.celsiusgs.com/blog/tag/spinlock/ https://developer.apple.com/library/mac/documentation/System/Reference/OSAtomic_header_reference/Reference/reference.html