《OC高級編程》筆記3——關(guān)于并發(fā)越除,關(guān)于GCD

最近在看GCD,閱讀了很多網(wǎng)上的資料,發(fā)現(xiàn)有很多資料寫得非常好摘盆,即全面而又詳細翼雀。自己功力還未到火候,對并發(fā)的理解及研究肯定不如他們孩擂,所以本篇主要收集幾篇關(guān)于并發(fā)的好文章狼渊。
小笨狼漫談多線程:GCD(1)
GCD 掃盲篇
深入理解 GCD(一)
深入理解 GCD(二)

objc中國上并發(fā)編程專題:
并發(fā)編程:API 及挑戰(zhàn)
常見的后臺實踐
底層并發(fā) API
常見的后臺實踐
線程安全類的設(shè)計

關(guān)于線程、多線程类垦。并發(fā)囤锉、并行。


1. 什么是線程护锤、單線程、多線程酿傍?

線程即一個CPU執(zhí)行的命令列為一條無分叉路徑烙懦。只有一條這樣的無分叉的路徑就叫單線程,多條則叫多線程赤炒。

也就是說一個CPU核一次只能執(zhí)行一條CPU的命令氯析,即CPU本來是單線程運作的,那多線程是怎樣實現(xiàn)的呢莺褒?

2.多線程是怎么實現(xiàn)的掩缓?

上下文切換:當只有一個CPU核時,系統(tǒng)會每隔一點時間反復來回切換執(zhí)行路徑遵岩,切換時將各路徑的一些狀態(tài)信息保存在路徑響應(yīng)的內(nèi)存中你辣,等下次切換回來時用。
這個切換時間是如此之快尘执,以至于讓人感覺到一個CPU好像能并列舍哄、同時處理多個線程一樣。而若有多個CPU核誊锭,那則才是真正意義上的并列表悬、同時執(zhí)行。
也就是說單核CPU的多線程是一種多線程的錯覺丧靡,而多核CPU的多線程確實是真正意義上的多線程蟆沫。

3.多線程可能引發(fā)的問題?

爭奪共享資源:比較常見的是多線程讀寫共享資源時可能隱藏這潛在的風險温治,結(jié)果不可靠饭庞。
我們來舉一個關(guān)于爭奪共享資源的簡單示例:用整型變量做計數(shù)器。在程序運行過程中罐盔,我們有兩個并行的線程A和線程B但绕,這兩個線程都可能嘗試修改整數(shù)的值。
那此時存在著什么偶然情況呢?如下圖捏顺,Thread A先開始修改該整數(shù)六孵,它先從內(nèi)存中讀取出該整數(shù)的值17,就在將要給其+1而未加之際幅骄。Thread B也開始修改該整數(shù)了劫窒,它讀取了該整數(shù)的內(nèi)存,因為Thread A還未對其進行+1操作拆座,或者雖在進行中但還未把結(jié)果18寫入該整數(shù)的內(nèi)存主巍。總之就是Thread B讀取到的整數(shù)值也還是17挪凑。接著Thread A和Thread B分別對該整數(shù)完成了+1操作孕索。因為兩者讀取到的初始值都是17,所以最終結(jié)果竟然是18躏碳。這明顯是錯誤的搞旭,對一個數(shù)進行了兩次+1操作,結(jié)果應(yīng)當是19才對菇绵。

爭奪共享資源.png

因此在多線程下訪問共享資源肄渗,某線程操作某資源時,應(yīng)該排斥限制其他線程訪問該資源咬最。這樣互斥機制應(yīng)運而生翎嫡。為避免出現(xiàn)以上潛在風險,某個線程在操作某資源前得先獲取一個互斥鎖永乌,將其他想訪問該資源而虎視眈眈的線程拒之門外惑申。等這個線程對資源操作完了再釋放掉鎖,這樣別的線程就有機會訪問該共享資源了翅雏。

加了互斥鎖.png

OC中定義屬性時硝桩,語義修飾詞atomicnonatomic分別代表“原子性”和“非原子性”。將屬性聲明為atomic代表在每次訪問該屬性時都會進行隱式的加鎖和解鎖枚荣。最可靠的做法是將所有的屬性都聲明為atomic碗脊,但是也會為加解鎖付出一定的代價。因此最終選擇是否加鎖橄妆,在于安全和性能的權(quán)衡衙伶。

在資源上加鎖會引發(fā)一定的性能代價,這些代價來源于:

獲取鎖本身就是開銷害碾,而且有時該鎖已經(jīng)被其他線程獲取了矢劲,所以當前線程得等待,此時線程便進入了休眠狀態(tài)慌随。當其他線程釋放掉相關(guān)資源的鎖時芬沉,休眠的線程會得到通知躺同,才進入就緒狀態(tài)獲取鎖。

而且若是獲取資源的鎖后丸逸,對該資源進行的操作比較復雜蹋艺,需要消耗比較長的時間,那其他線程想獲取鎖只好等你執(zhí)行完釋放掉鎖黄刚。比如本來計劃秉性運行的代碼捎谨,但實際上由于共享資源中配置了相關(guān)的鎖,所以同一時間只有一個線程是處于激活狀態(tài)的憔维。

死鎖
優(yōu)先級反轉(zhuǎn)

GCD的多線程


在GCD中涛救,開發(fā)者要做的只是把需要執(zhí)行的任務(wù)追加到合適的Dispatch Queue(隊列)中,開發(fā)者不需要親手管理線程业扒。而一般的所說的任務(wù)是以block形式表現(xiàn)的检吆。

1.關(guān)于隊列:Dispatch Queue

GCD中以執(zhí)行邏輯的不同可分為兩種隊列:串行隊列&并行隊列

  • ** 串行隊列:**隊列中的任務(wù),必須等上一個執(zhí)行結(jié)束程储,才能開始一下任務(wù)咧栗。

串行隊列只存在于一個線程中執(zhí)行任務(wù);而若手動創(chuàng)建多個串行隊列虱肄,雖然每個都只有一個線程,但多個串行隊列卻是并行的交煞。這樣仍然能達到并發(fā)的效果咏窿。

  • ** 并行隊列:**一個接一個的開始,并不等待上一個任務(wù)執(zhí)行完就開始下一個任務(wù)素征。

所謂“并行隊列”集嵌,就是在一個并行隊列中系統(tǒng)使用多個線程來同時執(zhí)行多個任務(wù),只不過這些線程是由系統(tǒng)來管理的御毅,作為開發(fā)者并不需要關(guān)心根欧。而且到底開啟多少線程,這個也是由系統(tǒng)決定的端蛆。

2.與同步凤粗、異步的區(qū)分

sync&async.png

** 同步:將任務(wù)提交給隊列后,等待任務(wù)完成后才返回今豆。
** 異步:
將任務(wù)提交給隊列后嫌拣,不等待任務(wù),而是立馬返回呆躲。** 異步必定會另開一個線程异逐,用于處理任務(wù)。**

屏幕快照 2016-04-19 下午2.03.40.png
3.創(chuàng)建隊列

** 自己手動創(chuàng)建:**

    // 串行隊列
    dispatch_queue_t mySerQueue = dispatch_queue_create("mySerialDispatchQueue.GCDDemo", DISPATCH_QUEUE_SERIAL);
    
    // 并行隊列
    dispatch_queue_t myConQueue = dispatch_queue_create("myConcurrentDispatchQueue.GCDDemo",DISPATCH_QUEUE_CONCURRENT);

GCD是C的函數(shù)插掂,沒有自動管理內(nèi)存的技術(shù)灰瞻,所以我們create的東西一定要自己釋放腥例,相應(yīng)的有方法release、retain方法酝润。
** 獲取系統(tǒng)提供的標準隊列:**
Main Dispatch Queue :在主線程中執(zhí)行的Dispatch Queue燎竖。因為主線程只有一個,所以Main Dispatch Queue為串行隊列袍祖。
Global Dispatch Queue:存在于系統(tǒng)的底瓣,所有程序都能夠使用的并發(fā)隊列,沒有必要通過create方法手動創(chuàng)建蕉陋,只要用時獲取系統(tǒng)的并行隊列就行了捐凭。
另外,Global Dispatch Queue有4個優(yōu)先級凳鬓。
另外茁肠,通過獲取系統(tǒng)隊列的方法獲取到的Main Dispatch Queue和Global Dispatch Queue執(zhí)行dispatch_retain和dispathc_release不會有任何變化,也不會有任何問題缩举。這也是獲取系統(tǒng)隊列比手動自己創(chuàng)建隊列簡單方便的原因垦梆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仅孩,隨后出現(xiàn)的幾起案子托猩,更是在濱河造成了極大的恐慌,老刑警劉巖辽慕,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件京腥,死亡現(xiàn)場離奇詭異,居然都是意外死亡溅蛉,警方通過查閱死者的電腦和手機公浪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來船侧,“玉大人欠气,你說我怎么就攤上這事【盗茫” “怎么了预柒?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長袁梗。 經(jīng)常有香客問我卫旱,道長,這世上最難降的妖魔是什么围段? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任顾翼,我火速辦了婚禮,結(jié)果婚禮上奈泪,老公的妹妹穿的比我還像新娘适贸。我一直安慰自己灸芳,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布拜姿。 她就那樣靜靜地躺著烙样,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蕊肥。 梳的紋絲不亂的頭發(fā)上谒获,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音壁却,去河邊找鬼批狱。 笑死,一個胖子當著我的面吹牛展东,可吹牛的內(nèi)容都是我干的赔硫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盐肃,長吁一口氣:“原來是場噩夢啊……” “哼爪膊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砸王,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤推盛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谦铃,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耘成,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年荷辕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片件豌。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡疮方,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茧彤,到底是詐尸還是另有隱情骡显,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布曾掂,位于F島的核電站惫谤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珠洗。R本人自食惡果不足惜溜歪,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望许蓖。 院中可真熱鬧蝴猪,春花似錦调衰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至沛豌,卻和暖如春趋箩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背加派。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工叫确, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哼丈。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓启妹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親醉旦。 傳聞我的和親對象是個殘疾皇子饶米,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

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