iOS中讀寫鎖的簡(jiǎn)單實(shí)現(xiàn)方法實(shí)例
廢話開篇
iOS 下的多線程的技術(shù)的應(yīng)用衍生出了鎖的機(jī)制,試想,如果 iOS 下沒(méi)有多線程的概念,所有的代碼都會(huì)在同步環(huán)境下執(zhí)行,那么,也就不會(huì)產(chǎn)生爭(zhēng)奪資源情況的發(fā)生,當(dāng)然,也就沒(méi)有辦法利用多核的優(yōu)勢(shì)。所以,多線程的應(yīng)用是廣布的,而鎖的應(yīng)用是局部的,所以,二者應(yīng)相輔相成,來(lái)達(dá)到提高運(yùn)行效率的同時(shí)提高程序運(yùn)行的穩(wěn)定性。
思考一、對(duì)于鎖的類型的理解
基本的三種鎖的類型:互斥鎖、自旋鎖、讀寫鎖。
其中,互斥鎖 多線程在訪問(wèn)加鎖中的臨界區(qū)前,會(huì)進(jìn)入休眠,一直等待解鎖后系統(tǒng)調(diào)度
;自旋鎖 多線程在訪問(wèn)加鎖中的臨界區(qū)前,不進(jìn)入休眠,會(huì)一直忙等。 讀寫鎖 是一種思想,本質(zhì)就是利用 互斥鎖 來(lái)實(shí)現(xiàn)特定的應(yīng)用場(chǎng)景:多讀并行、讀與寫互斥,寫與寫互斥;對(duì)于其他的類型的鎖,比如:信號(hào)量、條件鎖、遞歸鎖,可以理解為是由以上基本類型的鎖實(shí)現(xiàn)的上層封裝。
思考二、讀寫鎖的實(shí)現(xiàn)邏輯
如果有這樣一塊公共資源,它的寫入是比較耗時(shí),那么,在這段時(shí)間內(nèi)要避免程序再次的進(jìn)行寫入操作和讀取操作,這樣可以避免產(chǎn)生爭(zhēng)奪資源的問(wèn)題,當(dāng)然,讀取的過(guò)程可以并行。
先上一段代碼,這里模擬一個(gè)比較耗時(shí)的寫入過(guò)程,在模擬一個(gè)快速讀取的過(guò)程。
//讀寫鎖 - (void)readAndWriteLock { //寫 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"我開始寫"); for (int i = 0; i < 10000; i++) { } NSLog(@"我寫完了"); }); //讀 for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"我開始讀%d",i); for (int j = 0; j < i; j++) { } NSLog(@"我讀完了%d",i); }); } }
在寫入的異步內(nèi)執(zhí)行了循環(huán) 10000 次的操作來(lái)模擬耗時(shí)任務(wù);后面開辟了多線程進(jìn)行讀取,在讀取的異步里,實(shí)現(xiàn)簡(jiǎn)單的不同數(shù)量的循環(huán)來(lái)模擬耗時(shí)任務(wù),這里的耗時(shí)次數(shù)遠(yuǎn)小于寫入。
打印如下
通過(guò)輸出可以清晰的看到,寫入過(guò)程中還有很多讀取的操作在同時(shí)進(jìn)行。致于是先開始讀取還是開始寫入,這里其實(shí)并不用去關(guān)心,本身它們也是由系統(tǒng)決定的,但是,這里需要控制一下代碼,來(lái)實(shí)現(xiàn)讀寫互斥,即在寫的過(guò)程中,禁止讀取操作的介入。同時(shí),也需要實(shí)現(xiàn)寫寫互斥。對(duì)于,多讀,其實(shí)這里并不需要過(guò)多干涉,因?yàn)?,本身就允許多讀的邏輯。
思考三、簡(jiǎn)單封裝讀寫鎖,滿足讀寫邏輯
利用互斥鎖封裝讀取加、解鎖;寫入加、解鎖
//初始化讀取鎖 static pthread_mutex_t r_plock = PTHREAD_MUTEX_INITIALIZER; //初始化寫入鎖 static pthread_mutex_t w_plock = PTHREAD_MUTEX_INITIALIZER; //記錄當(dāng)前讀取次數(shù),因?yàn)橹灰渲挡粸?,那么,就說(shuō)明程序在讀取操作,這里停止寫入操作 static int current_read_times = 0;
進(jìn)行讀取加鎖
//讀加鎖 - (void)readLock { pthread_mutex_lock(&r_plock); current_read_times ++; if (current_read_times == 1) { pthread_mutex_lock(&w_plock); } pthread_mutex_unlock(&r_plock); }
這里首先進(jìn)行 讀取鎖 加鎖,這里加鎖的目的并不是鎖定讀取過(guò)程,而是鎖定了修改 current_read_times 的過(guò)程,當(dāng) current_read_times 變更后,如果為 1,那么,就對(duì) 寫入鎖 加鎖,這個(gè)寫入鎖就是鎖住寫入過(guò)程的。這兩個(gè)鎖的應(yīng)用部分是有區(qū)別的。
進(jìn)行讀取解鎖
//讀解鎖 - (void)readUnLock { pthread_mutex_lock(&r_plock); current_read_times --; if (current_read_times == 0) { pthread_mutex_unlock(&w_plock); } pthread_mutex_unlock(&r_plock); }
這里首先進(jìn)行 讀取鎖 加鎖,目的還是對(duì) current_read_times 修改的鎖,可以總結(jié)一下,讀寫鎖本質(zhì)并不對(duì)多讀進(jìn)行限制,所以,這里的讀取鎖是鎖住 current_read_times 修改過(guò)程,在加鎖的情況下進(jìn)行 寫入鎖 狀態(tài)的變更,實(shí)現(xiàn) 讀與寫的互斥。后面進(jìn)行狀態(tài)判斷,如果 current_read_times 為 0,說(shuō)明當(dāng)前所以讀取完成了,那么,對(duì) 寫入鎖 進(jìn)行解鎖,解鎖后寫入操作就可以正常進(jìn)行。這里解鎖的判斷為 == 0 與 加鎖的判斷 == 1 是一對(duì),這樣就滿足了,一個(gè)加鎖過(guò)程對(duì)應(yīng)一個(gè)解鎖條件。不會(huì)出現(xiàn)只有加鎖后而沒(méi)有解鎖的情況。
進(jìn)行寫入加鎖
//寫加鎖 - (void)writeLock { pthread_mutex_lock(&w_plock); }
這里僅僅是對(duì) 寫入 操作進(jìn)行加鎖。
進(jìn)行寫入解鎖
//寫解鎖 - (void)writeUnLock { pthread_mutex_unlock(&w_plock); }
這里僅僅是對(duì) 寫入 操作進(jìn)行解鎖。
最后的代碼
//讀寫鎖 - (void)readAndWriteLock { //寫 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self writeLock]; NSLog(@"我開始寫"); for (int i = 0; i < 10000; i++) { } NSLog(@"我寫完了"); [self writeUnLock]; }); //讀 for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self readLock]; NSLog(@"我開始讀%d",i); for (int j = 0; j < i; j++) { } NSLog(@"我讀完了%d",i); [self readUnLock]; }); } }
打印如下
可以看待寫入過(guò)程是完整的一個(gè)打印順序,而讀取過(guò)程由于沒(méi)有鎖的保護(hù)并沒(méi)有按順序執(zhí)行。
一個(gè)簡(jiǎn)單的 讀寫鎖 就完成了。代碼拙劣,大神勿笑。
總結(jié)
到此這篇關(guān)于iOS中讀寫鎖的簡(jiǎn)單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)iOS讀寫鎖實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
iOS實(shí)現(xiàn)自定義起始時(shí)間選擇器視圖
本篇文章主要介紹了iOS實(shí)現(xiàn)自定義起始時(shí)間選擇器視圖,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06iOS 8使用UIBlurEffect實(shí)現(xiàn)毛玻璃特效
這篇文章主要為大家詳細(xì)介紹了iOS 8使用UIBlurEffect類和UIVisualEffectView類實(shí)現(xiàn)毛玻璃特效,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能(一)
這篇文章主要介紹了IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能,點(diǎn)擊獲取驗(yàn)證碼,進(jìn)入時(shí)間倒計(jì)時(shí),感興趣的小伙伴們可以參考一下2016-01-01IOS中UITextView或UITextField字?jǐn)?shù)限制的實(shí)現(xiàn)
這篇文章主要介紹了IOS中UITextView或UITextField字?jǐn)?shù)限制的實(shí)現(xiàn)的相關(guān)資料,希望通過(guò)本文能幫助到大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10iOS 設(shè)置導(dǎo)航條透明效果的實(shí)例代碼
本文通過(guò)實(shí)例代碼給大家介紹了ios 設(shè)置導(dǎo)航條透明效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-03-03iOS 利用動(dòng)畫和貝塞爾實(shí)現(xiàn)咻咻效果
這篇文章主要介紹了iOS 利用動(dòng)畫和貝塞爾實(shí)現(xiàn)咻咻效果的相關(guān)資料,需要的朋友可以參考下2016-09-09