iOS學(xué)習(xí)-鎖

在 iOS 中毅贮,鎖是多線程編程中的關(guān)鍵要素办悟,也是保證線程安全的重要手段之一。本文將介紹常見的幾種鎖及其使用場景滩褥,并提供相關(guān)的代碼示例病蛉。

iOS中的鎖主要可以分為兩大類,互斥鎖和自旋鎖,其他鎖都是這兩種鎖的延伸和擴展铺然。

一俗孝、自旋鎖

原理

自旋鎖是一種基于忙等待的鎖,當(dāng)多個線程訪問共享資源時魄健,自旋鎖會不停地進行循環(huán)檢查赋铝,直到獲取到鎖為止。自旋鎖的好處在于它避免了線程切換和上下文切換的開銷沽瘦,在多核 CPU 上革骨,自旋鎖可以充分利用 CPU 時間片,因此在鎖競爭不激烈的情況下析恋,自旋鎖的性能比互斥鎖好良哲。

使用場景

自旋鎖適用于以下場景:

  • 多個線程訪問共享資源的競爭不激烈,即鎖競爭不激烈助隧。
  • 訪問共享資源的時間很短筑凫,即不會發(fā)生線程掛起。

iOS只有一種自旋鎖:OSSpinLock并村,其使用方法如下:

#import <libkern/OSAtomic.h>

OSSpinLock spinLock = OS_SPINLOCK_INIT;

// 獲取鎖
OSSpinLockLock(&spinLock);

// 臨界區(qū)代碼

// 釋放鎖
OSSpinLockUnlock(&spinLock);

需要注意的是京闰,由于自旋鎖等待線程不會進入阻塞狀態(tài)尺碰,而是不斷嘗試獲取鎖啥繁,如果等待時間過長會導(dǎo)致CPU占用過高穷遂,從而影響應(yīng)用程序的性能栖茉。此外鲁豪,OSSpinLock還存在優(yōu)先級反轉(zhuǎn)的問題航背。

優(yōu)先級反轉(zhuǎn)指的是高優(yōu)先級的線程因等待低優(yōu)先級線程所持有的鎖而被阻塞的情況延柠。在這種情況下洗显,高優(yōu)先級的線程可能一直等待外潜,直到低優(yōu)先級的線程釋放鎖。并且高優(yōu)先級的線程會搶占CPU資源挠唆,低優(yōu)先級的線程得不到CPU調(diào)度处窥,進而延長了等待時間,導(dǎo)致高優(yōu)先級的任務(wù)被延遲執(zhí)行玄组。

由于這些原因滔驾,OSSpinLock已被蘋果廢棄。

二俄讹、互斥鎖

互斥鎖是一種常見的鎖哆致,用于保護臨界區(qū)代碼,防止多個線程同時訪問共享資源患膛。

與自旋鎖不同的是摊阀,互斥鎖會將未獲得鎖的線程掛起,等待鎖的釋放。這種操作需要進行上下文切換胞此,開銷較大臣咖,因此互斥鎖的性能不如自旋鎖。

iOS 中的常見互斥鎖包括 pthread_mutex_t漱牵、NSLock夺蛇、NSCondition、NSConditionLock酣胀、NSRecursiveLock等刁赦。

1.pthread_mutex_t

pthread_mutex是一種互斥鎖,它可以保證同一時間只有一個線程可以訪問共享資源灵临。pthread_mutex基于POSIX標(biāo)準(zhǔn)實現(xiàn)截型。

pthread_mutex與其他鎖機制相比,具有以下特點:

  • 輕量級儒溉,適合高并發(fā)場景宦焦。
  • 由于是C語言的庫,使用起來相對較復(fù)雜顿涣。

代碼示例

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 獲取鎖
pthread_mutex_lock(&mutex);

// 臨界區(qū)代碼

// 釋放鎖
pthread_mutex_unlock(&mutex);

2.NSLock

NSLock是一個簡單的互斥鎖波闹,它基于POSIX線程互斥鎖實現(xiàn)。

代碼示例

NSLock *lock = [[NSLock alloc] init];

// 獲取鎖
[lock lock];

// 臨界區(qū)代碼

// 釋放鎖
[lock unlock];

3. NSCondition

NSCondition是一種條件鎖涛碑,它可以讓線程在某個條件滿足時等待精堕,并在條件滿足時喚醒線程。NSCondition基于pthread_cond_t和pthread_mutex_t實現(xiàn)蒲障。

NSCondition適用于以下場景:

  • 需要等待某個條件滿足后再進行訪問的場景歹篓。
  • 支持多個條件等待和喚醒的場景。

代碼示例

// 初始化條件鎖和條件變量
NSCondition *condition = [[NSCondition alloc] init];
BOOL conditionMet = NO;

- (void)waitExample {
    // 等待條件滿足
    [condition lock];
    while (!conditionMet) {
        [condition wait];
    }
    // 訪問共享資源
    // 釋放鎖
    [condition unlock];
}

- (void)signalExample {
    // 喚醒等待的線程
    [condition lock];
    conditionMet = YES;
    [condition signal];
    [condition unlock];
}

4. NSConditionLock

NSConditionLock是一種條件鎖揉阎,它可以讓線程在不同的條件下等待庄撮。NSConditionLock基于NSCondition和一個內(nèi)部的狀態(tài)變量實現(xiàn)。

NSConditionLock與其他鎖機制相比毙籽,具有以下特點:

  • 支持多個條件等待和喚醒洞斯。
  • 支持在不同的條件下等待。

代碼示例

// 初始化條件鎖
NSConditionLock *conditionLock = [[NSConditionLock alloc] initWithCondition:0];

- (void)conditionLockExample {
    // 等待條件1
    [conditionLock lockWhenCondition:0];

    // 訪問共享資源

    // 設(shè)置條件2
    [conditionLock unlockWithCondition:1];

    // 等待條件2
    [conditionLock lockWhenCondition:1];

    // 訪問共享資源

    // 釋放鎖
    [conditionLock unlock];
}

5. NSRecursiveLock

NSRecursiveLock是一種遞歸鎖坑赡,它允許同一個線程多次獲取鎖烙如,避免死鎖。

NSRecursiveLock與其他鎖機制相比毅否,具有以下特點:

  • 支持遞歸鎖亚铁,同一線程可以多次獲取同一把鎖,避免死鎖搀突。
  • NSRecursiveLock的性能比NSLock略低刀闷,因為它需要維護額外的狀態(tài)以支持遞歸鎖熊泵。

代碼示例

// 初始化遞歸鎖
NSRecursiveLock *recursiveLock = [[NSRecursiveLock alloc] init];

- (void)recursiveLockExample {
    // 獲取遞歸鎖
    [recursiveLock lock];

    // 訪問共享資源

    // 再次獲取遞歸鎖
    [recursiveLock lock];

    // 訪問共享資源

    // 釋放遞歸鎖
    [recursiveLock unlock];

    // 釋放遞歸鎖
    [recursiveLock unlock];
}

三. 信號量

原理

信號量是一種常見的并發(fā)控制機制,用于控制對共享資源的訪問甸昏。當(dāng)多個線程訪問共享資源時顽分,信號量可以用來限制并發(fā)訪問的數(shù)量。信號量有一個計數(shù)器施蜜,每個線程訪問共享資源前需要獲取信號量卒蘸,如果計數(shù)器為0,則線程需要等待翻默,直到其他線程釋放信號量為止缸沃。如果計數(shù)器不為0,則線程可以訪問共享資源修械,并將計數(shù)器減1趾牧。當(dāng)線程訪問完共享資源后,需要釋放信號量肯污,使計數(shù)器加1翘单,以便其他線程可以訪問共享資源。

區(qū)別

與互斥鎖和自旋鎖不同的是蹦渣,信號量可以控制對共享資源的并發(fā)訪問數(shù)量哄芜,因此它更適合用于限制并發(fā)度較高的情況。

使用場景
  • 多個線程訪問共享資源的競爭激烈柬唯,即鎖競爭激烈认臊。
  • 需要控制并發(fā)訪問的數(shù)量。

代碼示例

// 初始化信號量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

- (void)lockExample {
    // 等待信號量
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // 訪問共享資源
    // 釋放信號量
    dispatch_semaphore_signal(semaphore);
}

總結(jié)

本文介紹了iOS開發(fā)中常見的五種鎖機制:互斥鎖锄奢、自旋鎖失晴、信號量、讀寫鎖和GCD同步鎖拘央。對于每種鎖機制师坎,我們講解了它的原理、區(qū)別堪滨、使用場景和代碼示例,以便開發(fā)者可以根據(jù)實際情況選擇合適的鎖機制來實現(xiàn)多線程訪問控制蕊温。在實際開發(fā)中袱箱,我們需要根據(jù)具體的場景選擇合適的鎖機制,以保證多線程程序的正確性和效率义矛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末发笔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凉翻,更是在濱河造成了極大的恐慌了讨,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異前计,居然都是意外死亡胞谭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門男杈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丈屹,“玉大人,你說我怎么就攤上這事伶棒⊥荩” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵肤无,是天一觀的道長先蒋。 經(jīng)常有香客問我,道長宛渐,這世上最難降的妖魔是什么竞漾? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮皇忿,結(jié)果婚禮上畴蹭,老公的妹妹穿的比我還像新娘。我一直安慰自己鳍烁,他們只是感情好叨襟,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幔荒,像睡著了一般糊闽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爹梁,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天右犹,我揣著相機與錄音,去河邊找鬼姚垃。 笑死念链,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的积糯。 我是一名探鬼主播掂墓,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼看成!你這毒婦竟也來了君编?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤川慌,失蹤者是張志新(化名)和其女友劉穎吃嘿,沒想到半個月后祠乃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡兑燥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年亮瓷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贪嫂。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡寺庄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出力崇,到底是詐尸還是另有隱情斗塘,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布亮靴,位于F島的核電站馍盟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茧吊。R本人自食惡果不足惜贞岭,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搓侄。 院中可真熱鬧瞄桨,春花似錦、人聲如沸讶踪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乳讥。三九已至柱查,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間云石,已是汗流浹背唉工。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留汹忠,地道東北人淋硝。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像宽菜,于是被迫代替她去往敵國和親奖地。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Q:為什么出現(xiàn)多線程赋焕? A:為了實現(xiàn)同時干多件事的需求(并發(fā)),同時進行著下載和頁面UI刷新仰楚。對于處理器隆判,為每個線...
    幸福相依閱讀 1,578評論 0 2
  • iOS中的鎖 前言 寫在前面: 臨界區(qū):指的是一塊對公共資源進行訪問的代碼犬庇,并非一種機制或是算法。 自旋鎖:是用于...
    ROBIN2015閱讀 894評論 0 7
  • 多線程系列篇章計劃內(nèi)容:iOS多線程編程(一) 多線程基礎(chǔ)[https://juejin.im/post/6890...
    賣饃工程師閱讀 540評論 0 3
  • 前言 iOS開發(fā)中由于各種第三方庫的高度封裝,對鎖的使用很少咬腕,剛好之前面試中被問到的關(guān)于并發(fā)編程鎖的問題欢峰,都是一知...
    iOS__開發(fā)者皮皮峰閱讀 556評論 1 5
  • 前言 iOS開發(fā)中由于各種第三方庫的高度封裝,對鎖的使用很少涨共,剛好之前面試中被問到的關(guān)于并發(fā)編程鎖的問題纽帖,都是一知...
    喵渣渣閱讀 3,700評論 0 33