iOS多線程同步技術之常用鎖的使用介紹

前言:在出現多線程競爭數據的時候往往離不開鎖,那么在這里給大家介紹下我們多線程同步技術的常用鎖?有下面這些

常用鎖如下:

?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資源。

?目前已經不再安全,可能會出現優(yōu)先級反轉問題,如果等待鎖的線程優(yōu)先級較高,它會一直占用著CPU資源,優(yōu)先級低的線程就無法釋放鎖。這個鎖在ios10之后廢棄了,被os_unfair_lock替代。需要導入頭文件#import?

OSSpinLock代碼實現:


2、os_unfair_lock

?os_unfair_lock用于取代不安全的OSSpinLock?,從iOS10開始才支持

?從底層調用看,等待os_unfair_lock鎖的線程會處于休眠狀態(tài),并非忙等

?需要導入頭文件#import?

?用來取代之前的SpinLock,ios10之后才有的

代碼實現如下:


3、?pthread_mutex

?互斥鎖,等待鎖的線程會處于休眠狀態(tài)。

?需要導入頭文件#import?

跨平臺的鎖,在linux等其他平臺底層都通用

?PTHREAD_MUTEX_RECURSIVE遞歸鎖允許同一線程對鎖從復加鎖,不是同一線程不允許。

?PTHREAD_MUTEX_NORMAL普通鎖:不允許線程從復加鎖,要加鎖需要等鎖解鎖后才能再加。

(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的進一步封裝,可以設置具體的條件值

7、 dispatch_semaphore信號量

?信號量

?信號量的初始值,可以用來控制線程并發(fā)訪問的最大數量

?信號量的初始值為1,代表同時只允許1條線程訪問資源,保證線程同步


?8、 dispatch_queue實現線程同步

?直接使用GCD的串行隊列可以實現線程同步的

dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);

? ? dispatch_sync(queue, ^{

? ? ? ? //同步實現的邏輯任務

? ? });

9、?@synchronized

?@synchronized是對mutex遞歸鎖的封裝

?源碼查看:objc4中的objc-sync.mm文件

?@synchronized(obj)內部會生成obj對應的遞歸鎖,然后進行加鎖、解鎖操作。相當于obj作為key,生成一個遞歸鎖value。存在一個哈希表中。

實現代碼:

@synchronized(obj對象){

? ? ? ? //任務...

? ? }

? ? @synchronized(self){

? ? ? ? //任務...

? ? }

10、iOS線程同步方案性能比較

上面介紹了常用鎖的使用,那么性能上面比較,我們平時該怎么選擇使用呢?

?性能從高到低排序

--os_unfair_lock?? ios10之后新出的,版本有兼容要求。

--OSSpinLock???? ios10廢棄了,存在優(yōu)先級反轉的問題。

--dispatch_semaphore?? 推薦使用

--pthread_mutex?? 推薦使用

--dispatch_queue(DISPATCH_QUEUE_SERIAL)

--NSLock

--NSCondition

--pthread_mutex(recursive)

--NSRecursiveLock

--NSConditionLock

--@synchronized?? 性能最差不推薦使用。

11、自旋鎖、互斥鎖比較?

目前的鎖大體分為:自旋鎖跟互斥鎖,如果在沒有獲得鎖的情況下自旋鎖的線程不會進入休眠,處于忙等,互斥鎖會進入休眠。

1)什么情況使用自旋鎖比較劃算?

(1)預計線程等待鎖的時間很短

(2)加鎖的代碼(臨界區(qū))經常被調用,但競爭情況很少發(fā)生

(3)CPU資源不緊張

(4)多核處理器

2)什么情況使用互斥鎖比較劃算?

(1)預計線程等待鎖的時間較長

(2)單核處理器

(3)臨界區(qū)有IO操作,IO是比較消耗CPU資源的。

(4)臨界區(qū)代碼復雜或者循環(huán)量大

(5)臨界區(qū)競爭非常激烈

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容