Objective-C 常用鎖的介紹

1. os_unfair_lock 互斥鎖

  • 需要導(dǎo)入#import <os/lock.h>
  • 取代不安全的SSpriLock,從iOS 10才開(kāi)始支持
  • 底層等待的鎖的線程,不會(huì)盲等,線程會(huì)處于休眠狀態(tài)。
os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
os_unfair_lock_lock(&lock);
os_unfair_lock_unlock(&lock);

2.OSSpinLock 自旋鎖

  • 需要引入頭文件#import <libkern/OSAtomic.h>,并且在ios 10以后就不建議使用
  • 它是個(gè)自旋鎖
    • 自旋鎖只要有一個(gè)線程鎖住后,其他線程會(huì)盲等(循環(huán)等待)鎖,那個(gè)線程搶到那個(gè)線程就會(huì)執(zhí)行
    • 會(huì)造成優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題
    • 如果等待鎖的優(yōu)先級(jí)比較高,它會(huì)一直占用CPU資源,優(yōu)先級(jí)低的線程無(wú)法釋放鎖
// 初始換一個(gè)lock
OSSpinLock lock = OS_SPINLOCK_INIT;
// 開(kāi)始鎖
OSSpinLockLock(&lock);
// 解鎖
OSSpinLockUnlock(&lock);

3.dispatch_semaphore 信號(hào)量

  • 我們可以設(shè)置dispatch_semaphorevalue,來(lái)設(shè)置最大的并發(fā)數(shù),當(dāng)我們?cè)O(shè)置為1的時(shí)候,則可以代表鎖來(lái)使用
dispatch_semaphore_t semaphonre =  dispatch_semaphore_create(1);
// wait 表示當(dāng)信號(hào)值 > 0的時(shí)候通過(guò),且信號(hào)值-1,
// 當(dāng)信號(hào)值 <= 0時(shí),表示等待,只到信號(hào)值 > 0 重復(fù)上一句
dispatch_semaphore_wait(semaphonre, DISPATCH_TIME_FOREVER);
// signal 表示信號(hào)值 +1
dispatch_semaphore_signal(semaphonre);

/**
  DISPATCH_TIME_FOREVER: 表示永久等待
  DISPATCH_TIME_NOW: 表示不等待
*/

4. pthread_mutex 互斥鎖

  • mutex為互斥鎖,等待鎖的線程會(huì)處于休眠狀態(tài)。
  • 需要導(dǎo)入頭文件#import <pthread.h>
  • 條件當(dāng)時(shí)用條件等待的時(shí)候會(huì)放開(kāi)當(dāng)前持有的鎖,等待signal或者broadcast后,再重新持有鎖,繼續(xù)執(zhí)行代碼
  • 里面分為,默認(rèn)鎖和遞歸鎖。遞歸鎖需要設(shè)置mutexattr的type為PTHREAD_MUTEX_RECURSIVE
  • 注意: 創(chuàng)建的mutex、attr、cond等在不實(shí)用的時(shí)候,需要調(diào)用響應(yīng)的dispose方法進(jìn)行銷(xiāo)毀
// 初始化屬性
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr)
// 設(shè)置屬性
/*
PTHREAD_MUTEX_NORMAL 默認(rèn)
PTHREAD_MUTEX_RECURSIVE  遞歸鎖
PTHREAD_MUTEX_ERRORCHECK  錯(cuò)誤鎖
*/
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
// 初始化鎖
pthread_mutex_t mutex = {0};
// 第二個(gè)參數(shù)也可以填寫(xiě)為null,表示初始話一個(gè)默認(rèn)的??
pthread_mutex_init(&mutex,&attr);
// 銷(xiāo)毀類(lèi)型
pthread_mutexattr_destroy(&attr);
// 初始化條件
pthread_condattr_t condattr;
pthread_condattr_init(&condattr);
// 第二個(gè)參數(shù)也可以填寫(xiě)null,初始化一個(gè)默認(rèn)的添加
pthread_cond_init(&_cond, &condattr);

// 加??
pthread_mutex_lock(&_mutex);
// 解鎖
pthread_mutex_unlock(&_mutex);

// 條件等待
pthread_cond_wait(&_cond, &_mutex);
// 放開(kāi)其中一個(gè)鎖
pthread_cond_signal(&_cond);
// 發(fā)送一個(gè)廣播,放開(kāi)所有等待的鎖
pthread_cond_broadcast(&_cond);

5.NSLock

  • 是對(duì)pthread_mutex普通(默認(rèn))鎖的一個(gè)Objective-c的一個(gè)封裝。
  • 是一個(gè)互斥鎖。
// 嘗試加鎖
- (BOOL)tryLock;
// 在這個(gè)時(shí)間之前加鎖,如果加鎖成功,則返回yes,不成功則為false
- (BOOL)lockBeforeDate:(NSDate *)limit;
- (void)lock;
- (void)unlock;

注意:NSLock在上一次lock之后并沒(méi)有unlok之前再次lock之后,會(huì)造成永遠(yuǎn)的死鎖。

6.NSCondition

  • 是對(duì)pthread_mutex默認(rèn)鎖 和 cond的封裝
- (void)wait;
- (BOOL)waitUntilDate:(NSDate *)limit;
- (void)signal;
- (void)broadcast;

7.NSConditionLock

  • NSConditionLock是對(duì)NSCondition的封裝,多出condition條件屬性,可以根據(jù)自己的邏輯來(lái)設(shè)置不同的條件condition
  • 一般可以設(shè)置線程之間的依賴(lài)

// 當(dāng)滿足condition的時(shí)候才加鎖
- (void)lockWhenCondition:(NSInteger)condition; 
//嘗試獲取鎖對(duì)象,獲取成功需要配對(duì)unlock
- (BOOL)tryLock;
// 嘗試滿足condition加鎖
- (BOOL)tryLockWhenCondition:(NSInteger)condition; //同上
//解鎖,并且設(shè)置lock.condition = condition
- (void)unlockWithCondition:(NSInteger)condition; 

8.NSRecursiveLock 遞歸鎖

  • 是對(duì)pthread_mutex遞歸鎖的一個(gè)Objective-C的封裝
// 嘗試加鎖
- (BOOL)tryLock;
// 在這個(gè)時(shí)間之前加鎖,如果加鎖成功,則返回yes,不成功則為false
- (BOOL)lockBeforeDate:(NSDate *)limit;
- (void)lock;
- (void)unlock;

9.@synchronized 遞歸鎖

  • synchronized是對(duì)當(dāng)前對(duì)象進(jìn)行加鎖,且底層使用的是pthread_mutex里面的Recursive模式加鎖
  • 底層使用哈希表來(lái)儲(chǔ)存lock鎖對(duì)象之間的關(guān)聯(lián),使用的是鎖對(duì)象當(dāng)做key,lock當(dāng)作為值來(lái)儲(chǔ)存的哈西表里面。
  • 每次進(jìn)來(lái)時(shí)會(huì)從哈希表取出lock進(jìn)行??,結(jié)束的時(shí)候,會(huì)取出lock進(jìn)行unlock.

解釋?zhuān)?br> 遞歸鎖:表示同意線程可以多次重復(fù)加鎖,但是必須加鎖和解鎖為一一對(duì)應(yīng)。不同線程也是不可以多次加鎖
自旋鎖:表示等待加鎖的線程是一直循環(huán)等待,一直占用cpu資源
互斥鎖:表示等待加鎖的線程是處于休眠狀態(tài),等待鎖放開(kāi)后,喚起線程
自旋鎖、互斥鎖都是不可以在同一線程里面加鎖的,只有遞歸鎖是可以在同一線程加鎖

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

相關(guān)閱讀更多精彩內(nèi)容

  • 鎖是一種同步機(jī)制,用于多線程環(huán)境中對(duì)資源訪問(wèn)的限制iOS中常見(jiàn)鎖的性能對(duì)比圖(摘自:ibireme): iOS鎖的...
    LiLS閱讀 1,642評(píng)論 0 6
  • 轉(zhuǎn)自(https://bestswifter.com/ios-lock/#) 深入理解 iOS 開(kāi)發(fā)中的鎖 摘要 ...
    犯色戒的和尚閱讀 381評(píng)論 0 1
  • Q:為什么出現(xiàn)多線程? A:為了實(shí)現(xiàn)同時(shí)干多件事的需求(并發(fā)),同時(shí)進(jìn)行著下載和頁(yè)面UI刷新。對(duì)于處理器,為每個(gè)線...
    幸福相依閱讀 1,732評(píng)論 0 2
  • 1. 什么情況下會(huì)有線程隱患? 我們?cè)谑褂枚嗑€程技術(shù)帶來(lái)的便利的同時(shí),也需要考慮下多線程所帶來(lái)的隱患。比如,我們可...
    沉江小魚(yú)閱讀 892評(píng)論 0 11
  • 重溫電視劇《西游記》,倏然間看出了年少時(shí)看不出的感覺(jué)。 齊天大圣大鬧天宮后,玉帝派人請(qǐng)來(lái)了如來(lái)佛祖。 佛祖出現(xiàn)后,...
    枕藏寫(xiě)影視閱讀 372評(píng)論 1 1

友情鏈接更多精彩內(nèi)容