iOSでのロックメカニズム
3567 ワード
本論文では,OCにおける種々のロックの使用について主に論じた.まず、テスト用のクラスを作成します.このテストクラスが共有リソースであり、method 1とmethod 2が反発すると仮定します.テストクラス:
1.NSLockによるロック
NSLockは、lockメソッドとunlockメソッドに加えて、
2.synchronizedキーワードを使用して構築されたロック
@synchronized命令で使用されるobjは、このロックの一意の識別であり、識別が同じである場合にのみ反発を満たすために、スレッド2の
3.C言語を使用したpthread_mutex_t実装のロック
pthread_mutex_tはC言語の
4.GCDで実現した「ロック」
以上のコードでマルチスレッドを構築するには、GCDの
以上が一般的なロックメカニズムであり、ネット上で資料を調べると
OSSpinLockが安全かどうかの問題があれば、すぐに更新します.
#import "TestObject.h"
@implementation TestObject
- (void)method1
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}
- (void)method2
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}
@end
1.NSLockによるロック
TestObject *obj = [[TestObject alloc] init];
NSLock *lock = [[NSLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
[obj method1];
sleep(10);
[lock unlock];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);// 2
[lock lock];
[obj method2];
[lock unlock];
});
NSLockは、lockメソッドとunlockメソッドに加えて、
tryLock
とlockBeforeDate
の2つのメソッドを提供しています.前のメソッドは、ロックが使用できない場合(ロックされている場合)、スレッドをブロックせずにNOを返します.lockBeforeDate:メソッドは、指定したDateの前にロックを試み、指定した時間までにロックができない場合はNOを返します.2.synchronizedキーワードを使用して構築されたロック
TestObject *obj = [[TestObject alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(obj){
[obj method1];
sleep(10);
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
@synchronized(obj){
[obj method2];
}
});
@synchronized命令で使用されるobjは、このロックの一意の識別であり、識別が同じである場合にのみ反発を満たすために、スレッド2の
@synchronized(obj)
が@synchronized(other)
に変更されると、剛スレッド2がブロックされないため、@synchronized命令がロックを実現する利点は、コードに明示的に
を作成する必要がなく、ロックのメカニズムを実現することができるが、予防措置として、@synchronizedブロックは、異常放出時に自動的に反発ロックを解放する異常処理ルーチンを暗黙的に追加してコードを保護します.したがって、暗黙的な例外処理ルーチンに追加のオーバーヘッドをもたらしたくない場合は、ロックオブジェクトの使用を考慮することができます.3.C言語を使用したpthread_mutex_t実装のロック
TestObject *obj = [[TestObject alloc] init];
__block pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&mutex);
[obj method1];
sleep(5);
pthread_mutex_unlock(&mutex);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
pthread_mutex_lock(&mutex);
[obj method2];
pthread_mutex_unlock(&mutex);
});
pthread_mutex_tはC言語の
pthread.h
に定義されているので、インポートヘッダファイルは#include
を使用します.4.GCDで実現した「ロック」
以上のコードでマルチスレッドを構築するには、GCDの
dispatch_async
の方法が使用されていますが、実際にはGCDにも
が提供されています.これを使用して、「ロック」(本質的には、
と
は違いがあります.具体的な違いは、信号量と反発ロックの違いを自行で確認してください)
TestObject *obj = [[TestObject alloc] init];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[obj method1];
sleep(10);
dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[obj method2];
dispatch_semaphore_signal(semaphore);
});
以上が一般的なロックメカニズムであり、ネット上で資料を調べると
OSSpinLock
のスピンロック効率が最も高いと言われていますが、現在は多くの人がスピンロックが安全ではないと言っています.OSSpinLockを含めると、各種ロックの効率は以下の通りです.OSSpinLock > pthread_mutex > NSLock > semaphore > @Sych
OSSpinLockが安全かどうかの問題があれば、すぐに更新します.