多线程篇(被替换)
一. 背景
? 在剛接觸開發(fā)的頭幾年里,說(shuō)實(shí)話,根本不考慮多線程的這個(gè)問(wèn)題,貌似那時(shí)候腦子里也有沒(méi)有多線程的這個(gè)概念,所有的業(yè)務(wù)都是一個(gè)線程來(lái)處理,不考慮性能問(wèn)題,當(dāng)然也沒(méi)有考慮多線程操作一條記錄存在的并發(fā)問(wèn)題,后面隨著處理的系統(tǒng)業(yè)務(wù)越來(lái)越復(fù)雜,多線程再也回避不了了,也就借此機(jī)會(huì)深入研究了一下.Net中的多線程的處理方案。
發(fā)現(xiàn)在.Net領(lǐng)域領(lǐng)域中,多線程的處理大致經(jīng)歷了這么幾個(gè)階段:Thread→ThreadPool→委托的異步調(diào)用→Task→TaskFactory→Parallerl→async和await。
關(guān)注我博客的人會(huì)發(fā)現(xiàn),早在2017年6月份的時(shí)候,就開始整理多線程問(wèn)題了,大約用了6篇文章的來(lái)介紹了.Net中的線程的使用方法,主要是介紹相應(yīng)類的實(shí)例方法的使用,有點(diǎn)幫助文檔的意思了哦,最近多線程使用的相當(dāng)頻繁,借此機(jī)會(huì)重新結(jié)合一些實(shí)際業(yè)務(wù)系統(tǒng)介紹一下.Net領(lǐng)域的多線程問(wèn)題,本次將整合原先的六篇文章(刪除或覆蓋更新)。
PS:?多線程的本質(zhì)是犧牲空間來(lái)?yè)Q取時(shí)間,在同步方法中,邏輯代碼需要從上往下按順序執(zhí)行代碼塊,在很多情況下代碼塊與代碼塊之間并沒(méi)有先后依賴關(guān)系,而前面的代碼塊非常耗時(shí),在單線程下,后面的代碼塊必須等待前面的代碼塊執(zhí)行完畢才能執(zhí)行,在這種情況下,我們開辟出一個(gè)新線程去異步執(zhí)行前面的耗時(shí)代碼塊,而主線程繼續(xù)往后執(zhí)行,提高了執(zhí)行效率,這就是犧牲了空間換取了時(shí)間(現(xiàn)在的cpu都是2核4線程、4核心8線程,完全有能力處理多個(gè)線程)。
下面補(bǔ)充一下多線程在時(shí)間和空間上的開銷:
(一). 時(shí)間上:
①:開啟或銷毀一個(gè)線程都會(huì)通知進(jìn)出中的dll程序集,讓這些dll進(jìn)行相應(yīng)的操作。
②:時(shí)間片切換,cpu默認(rèn)最大支持8線程,但你開啟了9個(gè)線程,必然有一個(gè)線程會(huì)休眠。
(二). 空間上:
①:用戶模式堆棧,一個(gè)線程分配1M的堆棧空間。
②:內(nèi)核模式的堆棧,用戶模式的參數(shù)需要傳遞到內(nèi)核模式。
③:線程的內(nèi)核數(shù)據(jù)結(jié)構(gòu),會(huì)存放一下變量。
二. 概念的梳理
?1. 進(jìn)程、線程和多線程
進(jìn)程:當(dāng)一個(gè)程序開始運(yùn)行時(shí),它就是一個(gè)進(jìn)程,進(jìn)程包括運(yùn)行中的程序和程序所使用到的內(nèi)存和系統(tǒng)資源,而一個(gè)進(jìn)程又是由多個(gè)線程組成。
線程:線程是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器(棧指針、程序計(jì)數(shù)器等),但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。
多線程:多線程是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來(lái)執(zhí)行不同的任務(wù),也就是說(shuō)允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來(lái)完成各自的任務(wù)。
2. 多線程的好處和弊端
好處:可以提高CPU的利用率。在多線程程序中,一個(gè)線程必須等待的時(shí)候,CPU可以運(yùn)行其它的線程而不是等待,這樣就大大提高了程序的效率。(犧牲空間資源,來(lái)?yè)Q取時(shí)間)
弊端:
①:線程也是程序,所以線程需要占用內(nèi)存,線程越多占用內(nèi)存也越多;(占內(nèi)存多)
②:多線程需要協(xié)調(diào)和管理,所以需要CPU時(shí)間跟蹤線程;?(占cpu多)
③:線程之間對(duì)共享資源的訪問(wèn)會(huì)相互影響,必須解決競(jìng)用共享資源的問(wèn)題;(多線程存在資源共享問(wèn)題)
④:線程太多會(huì)導(dǎo)致控制太復(fù)雜,最終可能造成很多Bug。(管理麻煩,產(chǎn)生意外bug)
3. 何時(shí)建議使用多線程
①. 當(dāng)主線程試圖執(zhí)行冗長(zhǎng)的操作,但系統(tǒng)會(huì)卡界面,體驗(yàn)非常不好,這時(shí)候可以開辟一個(gè)新線程,來(lái)處理這項(xiàng)冗長(zhǎng)的工作。
②. 當(dāng)請(qǐng)求別的數(shù)據(jù)庫(kù)服務(wù)器、業(yè)務(wù)服務(wù)器等,可以開辟一個(gè)新線程,讓主線程繼續(xù)干別的事。
③. 利用多線程拆分復(fù)雜運(yùn)算,提高計(jì)算速度。
4. 何時(shí)不建議使用多線程
當(dāng)單線程能很好解決,就不要為了使用多線程而用多線程。
5. 同步方法和異步方法
①同步方法:方法從上而下一次執(zhí)行,一步一步執(zhí)行,有先后順序。
? ? ? ? ? ?
②異步方法:說(shuō)白了,就是里面有開啟了多個(gè)線程,主線程單獨(dú)執(zhí)行。
6. 異步多線程的三個(gè)特點(diǎn)
①:同步方法卡界面,原因是主線程被占用;異步方法不卡界面,原因是計(jì)算交給了別的線程,主線程空閑.
②:同步方法慢,原因是只有一個(gè)線程計(jì)算;異步方法快,原因是多個(gè)線程同時(shí)計(jì)算,但是更消耗資源,不宜太多.
②:異步多線程是無(wú)序的,啟動(dòng)順序不確定、執(zhí)行時(shí)間不確定、結(jié)束時(shí)間不確定.
?
三. 系列章節(jié)
? 第一節(jié):復(fù)習(xí)委托,并且通過(guò)委托的異步調(diào)用開啟一個(gè)新線程和異步回調(diào)、異步等待。
? 第二節(jié):深入剖析Thread的五大方法、數(shù)據(jù)槽、內(nèi)存柵欄。
? 第三節(jié):ThreadPool的線程開啟、線程等待、線程池的設(shè)置、定時(shí)功能。
? 第四節(jié):Task的啟動(dòng)的四種方式以及Task、TaskFactory的線程等待和線程延續(xù)的解決方案。
? 第五節(jié):Task構(gòu)造函數(shù)之TaskCreationOptions枚舉處理父子線程之間的關(guān)系。
? 第六節(jié):深入研究Task實(shí)例方法ContinueWith的參數(shù)TaskContinuationOptions。
? 第七節(jié):利用CancellationTokenSource實(shí)現(xiàn)任務(wù)取消和利用CancellationToken類檢測(cè)取消異常。
? 第八節(jié):Task的各類Task<TResult>返回值以及通用線程的異常處理方案。
? 第九節(jié):深究并行編程Parallel類中的三大方法 (For、ForEach、Invoke)和幾大編程模型(SPM、APM、EAP、TAP)
? 第十節(jié):利用async和await簡(jiǎn)化異步編程模式的幾種寫法
? 第十一節(jié):深究用戶模式鎖的使用場(chǎng)景(異變結(jié)構(gòu)、互鎖、旋轉(zhuǎn)鎖)
? 第十二節(jié):深究?jī)?nèi)核模式鎖的使用場(chǎng)景(自動(dòng)事件鎖、手動(dòng)事件鎖、信號(hào)量、互斥鎖、讀寫鎖、動(dòng)態(tài)鎖)
? 第十三節(jié):實(shí)際開發(fā)中使用最多的監(jiān)視鎖Monitor、lock語(yǔ)法糖的擴(kuò)展、混合鎖的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)
? 第十四節(jié): 介紹四大并發(fā)集合類并結(jié)合單例模式下的隊(duì)列來(lái)說(shuō)明線程安全和非安全的場(chǎng)景及補(bǔ)充性能調(diào)優(yōu)問(wèn)題。
? 第十五節(jié):
? 第十六節(jié):
? 第十七節(jié):
?
?
?
總結(jié)
- 上一篇: 开源软件巨头发布Euler Linux
- 下一篇: 《生化危机8:村庄》DLC难度比正篇要高