前言:在出現(xiàn)多線程競爭數(shù)據(jù)的時候往往離不開鎖,那么在這里給大家介紹下我們多線程同步技術(shù)的常用鎖?有下面這些
常用鎖如下:
?OSSpinLock
?os_unfair_lock
?pthread_mutex
?dispatch_semaphore
?dispatch_queue(DISPATCH_QUEUE_SERIAL)
?NSLock
?NSRecursiveLock
?NSCondition
?NSConditionLock
?@synchronized
1巩剖、OSSpinLock?
?OSSpinLock叫做”自旋鎖”样漆,等待鎖的線程會處于忙等(busy-wait)狀態(tài)焦蘑,一直占用著CPU資源。
?目前已經(jīng)不再安全芝此,可能會出現(xiàn)優(yōu)先級反轉(zhuǎn)問題靠胜,如果等待鎖的線程優(yōu)先級較高,它會一直占用著CPU資源饮醇,優(yōu)先級低的線程就無法釋放鎖它抱。這個鎖在ios10之后廢棄了,被os_unfair_lock替代朴艰。需要導(dǎo)入頭文件#import?
OSSpinLock代碼實(shí)現(xiàn):
2观蓄、os_unfair_lock
?os_unfair_lock用于取代不安全的OSSpinLock?,從iOS10開始才支持
?從底層調(diào)用看祠墅,等待os_unfair_lock鎖的線程會處于休眠狀態(tài)侮穿,并非忙等
?需要導(dǎo)入頭文件#import?
?用來取代之前的SpinLock,ios10之后才有的
代碼實(shí)現(xiàn)如下:
3毁嗦、?pthread_mutex
?互斥鎖亲茅,等待鎖的線程會處于休眠狀態(tài)。
?需要導(dǎo)入頭文件#import?
跨平臺的鎖狗准,在linux等其他平臺底層都通用
?PTHREAD_MUTEX_RECURSIVE遞歸鎖允許同一線程對鎖從復(fù)加鎖克锣,不是同一線程不允許。
?PTHREAD_MUTEX_NORMAL普通鎖:不允許線程從復(fù)加鎖腔长,要加鎖需要等鎖解鎖后才能再加娶耍。
(1)pthread_mutex?–?條件
4、NSLock饼酿、NSRecursiveLock
1)、NSLock是對mutex普通鎖的封裝,
?//創(chuàng)建鎖代碼
NSLock* lock = [[NSLock alloc]init];
2)胚膊、NSRecursiveLock也是對mutex遞歸鎖的封裝故俐,API跟NSLock基本一致;
5、 NSCondition
?NSCondition是對mutex和cond的封裝
6紊婉、NSConditionLock
?NSConditionLock是對NSCondition的進(jìn)一步封裝药版,可以設(shè)置具體的條件值
7、 dispatch_semaphore信號量
?信號量
?信號量的初始值喻犁,可以用來控制線程并發(fā)訪問的最大數(shù)量
?信號量的初始值為1槽片,代表同時只允許1條線程訪問資源,保證線程同步
?8肢础、 dispatch_queue實(shí)現(xiàn)線程同步
?直接使用GCD的串行隊(duì)列可以實(shí)現(xiàn)線程同步的
dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);
? ? dispatch_sync(queue, ^{
? ? ? ? //同步實(shí)現(xiàn)的邏輯任務(wù)
? ? });
9还栓、?@synchronized
?@synchronized是對mutex遞歸鎖的封裝
?源碼查看:objc4中的objc-sync.mm文件
?@synchronized(obj)內(nèi)部會生成obj對應(yīng)的遞歸鎖,然后進(jìn)行加鎖传轰、解鎖操作剩盒。相當(dāng)于obj作為key,生成一個遞歸鎖value慨蛙。存在一個哈希表中辽聊。
實(shí)現(xiàn)代碼:
@synchronized(obj對象){
? ? ? ? //任務(wù)...
? ? }
? ? @synchronized(self){
? ? ? ? //任務(wù)...
? ? }
10纪挎、iOS線程同步方案性能比較
上面介紹了常用鎖的使用,那么性能上面比較跟匆,我們平時該怎么選擇使用呢异袄?
?性能從高到低排序
--os_unfair_lock?? ios10之后新出的,版本有兼容要求玛臂。
--OSSpinLock???? ios10廢棄了烤蜕,存在優(yōu)先級反轉(zhuǎn)的問題。
--dispatch_semaphore?? 推薦使用
--pthread_mutex?? 推薦使用
--dispatch_queue(DISPATCH_QUEUE_SERIAL)
--NSLock
--NSCondition
--pthread_mutex(recursive)
--NSRecursiveLock
--NSConditionLock
--@synchronized?? 性能最差不推薦使用垢揩。
11玖绿、自旋鎖、互斥鎖比較?
目前的鎖大體分為:自旋鎖跟互斥鎖叁巨,如果在沒有獲得鎖的情況下自旋鎖的線程不會進(jìn)入休眠斑匪,處于忙等,互斥鎖會進(jìn)入休眠锋勺。
1)什么情況使用自旋鎖比較劃算蚀瘸?
(1)預(yù)計(jì)線程等待鎖的時間很短
(2)加鎖的代碼(臨界區(qū))經(jīng)常被調(diào)用,但競爭情況很少發(fā)生
(3)CPU資源不緊張
(4)多核處理器
2)什么情況使用互斥鎖比較劃算庶橱?
(1)預(yù)計(jì)線程等待鎖的時間較長
(2)單核處理器
(3)臨界區(qū)有IO操作贮勃,IO是比較消耗CPU資源的。
(4)臨界區(qū)代碼復(fù)雜或者循環(huán)量大
(5)臨界區(qū)競爭非常激烈