iOS多线程——锁
iOS多線程——鎖
在開發(fā)中,多線程編程是必不可少的,多線程的線程安全也是要考慮的,可能最有印象的應(yīng)該還是atomic屬性吧,其次就是GCD的dispatch_semaphore。于是就總結(jié)了一下,iOS開發(fā)中的線程安全措施。大致有如下幾種:
- atomic屬性
- @synchronize(對(duì)象)
- NSLock 需要提一下,lock、unlock方法必須在一個(gè)線程調(diào)用,這里說(shuō)的很清楚
- NSRecursiveLock 遞歸鎖,能在同一個(gè)線程多次請(qǐng)求不會(huì)死鎖
- NSCondition
- NSConditionLock
- OSSpinLock 自旋鎖,被棄用了,因?yàn)榇嬖趦?yōu)先級(jí)反轉(zhuǎn)問題,蘋果已經(jīng)棄用,并用os_unfair_lock作為替代。需要引入頭文件 #impot< libkern/OSAtomic.h>
os_unfair_lock 不公平的鎖,就是解決優(yōu)先級(jí)反轉(zhuǎn)問題。 需要引入頭文件 #import < os/lock.h>
pthread_mutex 創(chuàng)建需由pthread_attr_t參數(shù),如果參數(shù)attr為空,則使用默認(rèn)的互斥鎖屬性,默認(rèn)屬性為快速互斥鎖 。互斥鎖的屬性在創(chuàng)建鎖的時(shí)候指定,不同的鎖類型在試圖對(duì)一個(gè)已經(jīng)被鎖定的互斥鎖加鎖時(shí)表現(xiàn)不同。(#define PTHREAD_MUTEX_NORMAL
#define PTHREAD_MUTEX_ERRORCHECK
#define PTHREAD_MUTEX_RECURSIVE 三種屬性)至于不同屬性的性能,都是一家的,在這里就不比較了- dispatch_semaphore
既然有這么多的實(shí)現(xiàn)方式,當(dāng)然要一較高下,選擇自己喜歡的方式,于是寫了下面的測(cè)試代碼比較性能:
NSMutableArray *timeArr = [NSMutableArray array];CFTimeInterval start,end,cost;NSInteger count = 100000;NSArray *nameArr = @[@"OSSpinLock",@"NSLock",@"dispatch_semaphore",@"pthread_mutex",@"NSCondition",@"NSConditionLock",@"NSRecursiveLock",@"@synchronized",@"os_unfair_lock"];#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated"{OSSpinLock lock = OS_SPINLOCK_INIT;start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {OSSpinLockLock(&lock);OSSpinLockUnlock(&lock);}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];} #pragma clang pop{NSLock *lock = [NSLock new];start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {[lock lock];[lock unlock];}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{dispatch_semaphore_t lock = dispatch_semaphore_create(1);start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);dispatch_semaphore_signal(lock);}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{pthread_mutex_t lock;pthread_mutex_init(&lock, NULL);start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {pthread_mutex_lock(&lock);pthread_mutex_unlock(&lock);}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{NSCondition *lock = [NSCondition new];start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {[lock lock];[lock unlock];}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {[lock lock];[lock unlock];}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{NSRecursiveLock *lock = [NSRecursiveLock new];start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {[lock lock];[lock unlock];}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{NSObject *lock = [NSObject new];start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {@synchronized(lock) {}}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}{os_unfair_lock_t unfairLock;unfairLock = &(OS_UNFAIR_LOCK_INIT);start = CFAbsoluteTimeGetCurrent();for (int i = 0; i < count; i++) {os_unfair_lock_lock(unfairLock);os_unfair_lock_unlock(unfairLock);}end = CFAbsoluteTimeGetCurrent();cost = end - start;[timeArr addObject:@(cost)];}for (int i = 0; i < timeArr.count; i++) {NSLog(@"------%@------%@\n",timeArr[i],nameArr[i]);}最后打印結(jié)果如下:
------0.0009900331497192383------OSSpinLock------0.00348198413848877------NSLock------0.001325011253356934------dispatch_semaphore------0.002358973026275635------pthread_mutex------0.003148019313812256------NSCondition------0.01061898469924927------NSConditionLock------0.00425797700881958------NSRecursiveLock------0.0124550461769104------@synchronized------0.00145798921585083------os_unfair_lock可以看出要是沒有優(yōu)先級(jí)反轉(zhuǎn)的問題的話,osspinlock占有絕對(duì),其次就是dispatch_semaphore,dispatch_semaphore和os_unfair_lock差距很小,其次就是pthread_mutex。其實(shí)在測(cè)試的時(shí)候呢,性能和次數(shù)是有關(guān)系的,即是說(shuō)這幾種鎖在不同的情形下會(huì)發(fā)揮最好性能,次數(shù)量大的時(shí)候呢,性能排名就如上面一樣。所以在項(xiàng)目中使用的話,就根據(jù)項(xiàng)目情況選擇即可。
好吧!就到這里,對(duì)iOS鎖也算有了一定的了解。 還是那句話,如您發(fā)現(xiàn)任何錯(cuò)誤,歡迎留言指正~
總結(jié)
- 上一篇: rhel 7.2 mysql_Rhel7
- 下一篇: 信息安全保障人员CISAW--- 开班啦