我们在多线程编程中常常会使用一些锁来保证程序的线程安全,这篇主要就是介绍一些iOS中常用锁,以及通过一个简单的demo来测试一些锁的性能。
锁只要分为以下几类:
互斥锁它将代码切片成为一个个临界区(代码片段),使得当一个代码片段在运行时,其他线程不能运行它们之中的任意片段,只有等到该片段结束运行后才可以运行。通过这种方式来防止多个线程同时对某一资源进行读写的一种机制。
是并发控制的一种同步机制,有的地方也称为“共享-互斥锁”,也是一种特殊的自旋锁。它把对资源的访问者分为读者和写者。它允许同时有多个读者来访问资源,但是只允许一个写者来访问资源。
多线程同步的一种锁,当其检测到资源不可用时,则保持一种“忙等”的状态,知道获取该资源。因此它的优势在于避免了线程上下文的进度的切换,非常适合于阻塞时间很短的场合。缺点则是在“忙等”的状态下会不停检测状态,占用一点的cpu资源。
顾名思义,就是通过一些条件来控制资源的访问,当然条件是会发生变化的。
是一种高级的同步机制。互斥锁可以认为是型号量取值0/1时的特例,可以实现更加复杂的同步。
通过一个简单的demo来分析iOS中常用的一些锁的性能(@synchronized,NSLock,pthread,OSSpinLock,dispatch_semaphore_t,pthread_mutex_t,NSCondition,NSRecursiveLock,NSConditionLock,pthread_rwlock_t,os_unfair_lock_t,pthread_mutex_recursive)
demo的主要代码如下:
NSTimeInterval begin, end; //定义锁的开始时间和结束时间
// OSSpinLock 自旋锁
{
OSSpinLock lock = OS_SPINLOCK_INIT;
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
OSSpinLockLock(&lock);
OSSpinLockUnlock(&lock);
}
end = CACurrentMediaTime();
timeCosts = end - begin;
}
// dispatch_semaphore_t 信号量
dispatch_semaphore_t lock = dispatch_semaphore_create(1);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(lock);
}
end = CACurrentMediaTime();
timeCosts = end - begin;
// pthread_mutex_t
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
end = CACurrentMediaTime();
timeCosts = end - begin;
pthread_mutex_destroy(&lock);
// NSCondition 条件锁
NSCondition *lock = [NSCondition new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
timeCosts = end - begin;
// NSLock
NSLock *lock = [NSLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
timeCosts = end - begin;
pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
end = CACurrentMediaTime();
timeCosts = end - begin;
pthread_mutex_destroy(&lock);
// NSRecursiveLock 递归锁
NSRecursiveLock *lock = [NSRecursiveLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
timeCosts = end - begin;
// NSConditionLock
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
timeCosts = end - begin;
// pthread_rwlock_t 读写锁
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_rwlock_wrlock(&rwlock);
pthread_rwlock_unlock(&rwlock);
}
end = CACurrentMediaTime();
timeCosts = end - begin;
// os_unfair_lock_t iOS10之后的替换自旋锁的
os_unfair_lock_t unfairLock;
unfairLock = &(OS_UNFAIR_LOCK_INIT);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
os_unfair_lock_lock(unfairLock);
os_unfair_lock_unlock(unfairLock);
}
end = CACurrentMediaTime();
TimeCosts[LockTypeos_unfair_lock] += end - begin;
timeCosts[LockTypeos_unfair_lock] = end - begin;
// synchronized
NSObject *lock = [NSObject new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
@synchronized(lock) {}
}
end = CACurrentMediaTime();
TimeCosts[LockTypesynchronized] += end - begin;
timeCosts[LockTypesynchronized] = end - begin;
上述代码均为加锁解锁的操作,在重复1000000次加锁解锁的基础进行测试(模拟器中),结果数据如下:
OSSpinLock | os_unfair_lock | dispatch_semaphore | pthread_mutex | NSCondition | NSLock | pthread_rwlock | pthread_mutex(recursive) | NSRecursiveLock | NSConditionLock | @synchronized |
---|---|---|---|---|---|---|---|---|---|---|
13.31 ms | 15.03 ms | 18.33 ms | 23.85 ms | 24.08 ms | 26.65 ms | 28.21 ms | 37.22 ms | 48.09 ms | 88.04 ms | 137.27 ms |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。