iOS底層探索之多線程(十八)——鎖篇章的完結(jié)篇(手把手兩種方式帶你實(shí)現(xiàn)一個(gè)讀寫(xiě)鎖毛仪!)

iOS 開(kāi)發(fā)做瞪,各種鎖你了解多少对粪?NSLock、NSCondtion装蓬、NSRecursiveLock.......

回顧

上篇博客中已經(jīng)通過(guò) SwiftFoundation源碼分析NSLock著拭、NSCondtionNSRecursiveLock牍帚、NSCondition等鎖了儡遮,那么本篇博將手把手帶你實(shí)現(xiàn)一個(gè)讀寫(xiě)鎖

鎖你了解多少暗赶?

iOS底層探索之多線程(一)—進(jìn)程和線程

iOS底層探索之多線程(二)—線程和鎖

iOS底層探索之多線程(三)—初識(shí)GCD

iOS底層探索之多線程(四)—GCD的隊(duì)列

iOS底層探索之多線程(五)—GCD不同隊(duì)列源碼分析

iOS底層探索之多線程(六)—GCD源碼分析(sync 同步函數(shù)鄙币、async 異步函數(shù))

iOS底層探索之多線程(七)—GCD源碼分析(死鎖的原因)

iOS底層探索之多線程(八)—GCD源碼分析(函數(shù)的同步性、異步性蹂随、單例)

iOS底層探索之多線程(九)—GCD源碼分析(柵欄函數(shù))

iOS底層探索之多線程(十)—GCD源碼分析( 信號(hào)量)

iOS底層探索之多線程(十一)—GCD源碼分析(調(diào)度組)

iOS底層探索之多線程(十二)—GCD源碼分析(事件源)

iOS底層探索之多線程(十三)—鎖的種類(lèi)你知多少?

iOS底層探索之多線程(十四)—關(guān)于@synchronized鎖你了解多少?

iOS底層探索之多線程(十五)—@synchronized源碼分析

iOS底層探索之多線程(十六)——鎖分析(NSLock十嘿、NSCondtion、NSRecursiveLock岳锁、NSCondition)

iOS底層探索之多線程(十七)——通過(guò) Swift的Foundation源碼分析鎖(NSLock绩衷、NSCondition、NSRecursiveLock)

1. 什么是讀寫(xiě)鎖?

在開(kāi)始之前咳燕,先來(lái)了解一下勿决,什么是讀寫(xiě)鎖

  • 讀寫(xiě)鎖實(shí)際是?種特殊的?旋鎖招盲,它把對(duì)共享資源的訪問(wèn)者劃分成讀者寫(xiě)者剥险,讀者只對(duì)共享資源進(jìn)?讀訪問(wèn),寫(xiě)者則需要對(duì)共享資源進(jìn)?寫(xiě)操作宪肖。
  • 這種鎖相對(duì)于?旋鎖??,能提?并發(fā)性健爬,因?yàn)樵诙嗵幚砥飨到y(tǒng)中控乾,它允許同時(shí)有多個(gè)讀者來(lái)訪問(wèn)共享資源,最?可能的讀者數(shù)為實(shí)際的邏輯CPU數(shù)娜遵。
  • 寫(xiě)者是排他性的蜕衡,?個(gè)讀寫(xiě)鎖同時(shí)只能有?個(gè)寫(xiě)者或多個(gè)讀者(與CPU數(shù)相關(guān)),但不能同時(shí)既有讀者?有寫(xiě)者设拟,在讀寫(xiě)鎖保持期間也是搶占失效的慨仿。
  • 如果讀寫(xiě)鎖當(dāng)前沒(méi)有讀者,也沒(méi)有寫(xiě)者纳胧,那么寫(xiě)者可以?刻獲得讀寫(xiě)鎖镰吆,否則它必須?旋在那?,直到?jīng)]有任何寫(xiě)者或讀者跑慕。
  • 如果讀寫(xiě)鎖沒(méi)有寫(xiě)者万皿,那么讀者可以?即獲得該讀寫(xiě)鎖,否則讀者必須?旋在那?核行,直到寫(xiě)者釋放該讀寫(xiě)鎖牢硅。
  • ?次只有?個(gè)線程可以占有寫(xiě)模式的讀寫(xiě)鎖, 但是可以有多個(gè)線程同時(shí)占有讀模式的讀寫(xiě)鎖,正是因?yàn)檫@個(gè)特性芝雪,當(dāng)讀寫(xiě)鎖是寫(xiě)加鎖狀態(tài)時(shí)减余,在這個(gè)鎖被解鎖之前,所有試圖對(duì)這個(gè)鎖加鎖的線程都會(huì)被阻塞惩系。
  • 當(dāng)讀寫(xiě)鎖在讀加鎖狀態(tài)時(shí)位岔,所有試圖以讀模式對(duì)它進(jìn)?加鎖的線程都可以得到訪問(wèn)權(quán),但是如果線程希望以寫(xiě)模式對(duì)此鎖進(jìn)?加鎖蛆挫, 它必須直到所有的線程釋放鎖赃承。
  • 通常的情況是當(dāng)讀寫(xiě)鎖處于讀模式鎖住狀態(tài)時(shí),如果有另外線程試圖以寫(xiě)模式加鎖悴侵,讀寫(xiě)鎖通常會(huì)阻塞隨后的讀模式鎖請(qǐng)求瞧剖,這樣可以避免讀模式鎖?期占?,?等待的寫(xiě)模式鎖請(qǐng)求?期阻塞
  • 讀寫(xiě)鎖適合于對(duì)數(shù)據(jù)結(jié)構(gòu)的讀次數(shù)?寫(xiě)次數(shù)多得多的情況抓于。 因?yàn)? 讀模式鎖定時(shí)可以共享做粤, 以寫(xiě)模式鎖住時(shí)意味著獨(dú)占,所以讀寫(xiě)鎖?叫 共享-獨(dú)占鎖 捉撮。

那我們?cè)撊绻?code>封裝實(shí)現(xiàn)一個(gè)讀寫(xiě)鎖呢怕品?

首先我們要明白讀寫(xiě)鎖的核心功能是什么?毫無(wú)疑問(wèn)肯定是:多讀單寫(xiě)巾遭。

  • 多讀就是允許多條線程對(duì)這個(gè)內(nèi)存空間進(jìn)行讀取操作肉康。
  • 單寫(xiě)就是同一時(shí)刻只能有一個(gè)線程,對(duì)這一片內(nèi)存空間進(jìn)行寫(xiě)操作灼舍,如果有多個(gè)寫(xiě)操作吼和,數(shù)據(jù)肯定就錯(cuò)亂了,這是我們所不能允許的骑素。
  • 寫(xiě)與寫(xiě)要互斥:炫乓,A寫(xiě)完了,B才能進(jìn)行寫(xiě)献丑。
  • 讀與寫(xiě)要互斥:A在寫(xiě)的時(shí)候末捣,B不能讀,必須要等 A寫(xiě)完B再去讀创橄。
  • 讀寫(xiě)不能堵塞主線程箩做,不能影響正常的程序運(yùn)行。

既然所有的注意點(diǎn)和功能點(diǎn)都清楚了妥畏,那么廢話不多少卒茬,開(kāi)工吧!這里將通過(guò)兩種方式進(jìn)行實(shí)現(xiàn)分別是pthreadAPIGCDAPI咖熟。

2. pthread 實(shí)現(xiàn)讀寫(xiě)鎖

那么首先圃酵,我們先使用pthread來(lái)實(shí)現(xiàn)一下,模擬火車(chē)票的情況馍管,代碼如下:

//注意這里要導(dǎo)入頭文件
#import <pthread.h>

@interface ViewController ()

@property (nonatomic, assign) NSUInteger trainTickets;//火車(chē)票數(shù)量
@property (nonatomic, assign) pthread_rwlock_t jpLock;// 鎖

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.trainTickets = 0;
    [self jp_Test];
}
  • 讀操作
    // 讀方法
-(void)jP_read{
        // 讀加鎖
    pthread_rwlock_rdlock(&_jpLock);
    sleep(1);
    NSLog(@"讀取火車(chē)票數(shù)量為:%zd", self.trainTickets);
        // 解鎖
    pthread_rwlock_unlock(&_jpLock);
}
  • 寫(xiě)操作
    // 寫(xiě)方法
-(void)jP_write{
        // 寫(xiě)加鎖
    pthread_rwlock_wrlock(&_jpLock);

    sleep(1);
    NSLog(@"寫(xiě)入后火車(chē)票數(shù)量為:%zd", ++self.trainTickets);
        // 解鎖
    pthread_rwlock_unlock(&_jpLock);
}

  • 來(lái)看看運(yùn)行結(jié)果如何
代碼運(yùn)行結(jié)果

代碼完美運(yùn)行郭赐,非常完美!結(jié)果很正常确沸,沒(méi)有錯(cuò)亂捌锭!


厲害了,666
  • pthread API

  • pthread_rwlock_t lock; // 結(jié)構(gòu)

  • pthread_rwlock_init(&lock, null); // 初始化

  • pthread_rwlock_rdlock(&lock);// 讀加鎖

  • pthread_rwlock_tryrdlock(&lock); // 讀嘗試加鎖

  • pthread_rwlock_wdlock(&lock);// 寫(xiě)加鎖

  • pthread_rwlock_trywdlock(&lock); // 寫(xiě)嘗試加鎖

  • pthread_rwlock_unlock(&lock); // 解鎖

  • pthread_rwlock_destory(&lock); // 銷(xiāo)毀

3. GCD 實(shí)現(xiàn)讀寫(xiě)鎖

上面??已經(jīng)用pthread實(shí)現(xiàn)了讀寫(xiě)鎖罗捎,那么現(xiàn)在就用我們比較熟悉的 GCD來(lái)實(shí)現(xiàn)一下吧观谦!

  • GCD實(shí)現(xiàn)代碼如下:


    GCD實(shí)現(xiàn)代碼
  • GCD實(shí)現(xiàn)運(yùn)行結(jié)果如下:
GCD實(shí)現(xiàn)運(yùn)行架構(gòu)

結(jié)果和上面用pthread實(shí)現(xiàn)的效果是一樣的,這里就不過(guò)多分析了桨菜,代碼注釋都有豁状,相信大家都懂的捉偏!

你懂的!

4. 總結(jié)

  • 讀寫(xiě)鎖的核心功能就是多讀單寫(xiě)
  • 寫(xiě)與寫(xiě)要互斥
  • 讀與寫(xiě)要互斥
  • 讀寫(xiě)不能堵塞主線程泻红,不能影響正常的程序運(yùn)行夭禽。

更多內(nèi)容持續(xù)更新

?? 喜歡就點(diǎn)個(gè)贊吧????

?? 覺(jué)得有收獲的,可以來(lái)一波谊路,收藏+關(guān)注讹躯,評(píng)論 + 轉(zhuǎn)發(fā),以免你下次找不到我????

??歡迎大家留言交流缠劝,批評(píng)指正潮梯,互相學(xué)習(xí)??,提升自我??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惨恭,一起剝皮案震驚了整個(gè)濱河市酷麦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喉恋,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件母廷,死亡現(xiàn)場(chǎng)離奇詭異轻黑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)琴昆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)氓鄙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人业舍,你說(shuō)我怎么就攤上這事抖拦。” “怎么了舷暮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵态罪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我下面,道長(zhǎng)复颈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任沥割,我火速辦了婚禮耗啦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘机杜。我一直安慰自己帜讲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布椒拗。 她就那樣靜靜地躺著似将,像睡著了一般获黔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玩郊,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天肢执,我揣著相機(jī)與錄音,去河邊找鬼译红。 笑死预茄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侦厚。 我是一名探鬼主播耻陕,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼刨沦!你這毒婦竟也來(lái)了诗宣?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤想诅,失蹤者是張志新(化名)和其女友劉穎召庞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體来破,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篮灼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徘禁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诅诱。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖送朱,靈堂內(nèi)的尸體忽然破棺而出娘荡,到底是詐尸還是另有隱情,我是刑警寧澤驶沼,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布炮沐,位于F島的核電站,受9級(jí)特大地震影響回怜,放射性物質(zhì)發(fā)生泄漏央拖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一鹉戚、第九天 我趴在偏房一處隱蔽的房頂上張望鲜戒。 院中可真熱鬧,春花似錦抹凳、人聲如沸遏餐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)失都。三九已至柏蘑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粹庞,已是汗流浹背咳焚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留庞溜,地道東北人革半。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像流码,于是被迫代替她去往敵國(guó)和親又官。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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