并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发
多線程:
- 多線程就是同時執(zhí)行多個應用程序,需要硬件的支持
- 同時執(zhí)行:不是某個時間段同時,cpu切換的比較快,所有用戶會感覺是在同時運行
并發(fā)與并行:
-
并行(parallel):指在同一時刻,有多條指令在多個處理器上同時執(zhí)行。并行必須借助于多核cpu實現(xiàn)
-
并發(fā)(concurrency):指在同一時刻只能有一條指令執(zhí)行,但多個進程指令被快速的輪換執(zhí)行,使得在宏觀上具有多個進程同時執(zhí)行的效果,但在微觀上并不是同時執(zhí)行的,只是把時間分成若干段,通過cpu時間片輪轉使多個進程快速交替的執(zhí)行。
程序、線程、進程:
程序:是指編譯好的可執(zhí)行文件,程序啟動的時候,進程作為支撐
進程:是正在運行的程序(比如360殺毒軟件),進程可以產(chǎn)生多線程
獨立性:進程是一個能獨立運行的基本單位,同時也是系統(tǒng)分配資源和調(diào)度的獨立單位
動態(tài)性:進程的實質(zhì)是程序的一次執(zhí)行過程,進程是動態(tài)產(chǎn)生,動態(tài)消亡的
并發(fā)性:任何進程都可以同其他進程一起并發(fā)執(zhí)行
進程基本的狀態(tài)有5種:分別為初始態(tài)、就緒態(tài)、運行態(tài)、掛起態(tài)、終止態(tài)其中初始態(tài)為進程準備階段,常與就緒態(tài)結合來看。
每當有一個進程啟動系統(tǒng)都會打開三個文件,標準輸入文件(stdin)、標準輸出(stdout)、標準錯誤輸出文件(stderr),當進程運行結束系統(tǒng)會自動關閉三個文件。
- 標準輸入(stdin):一般都是對應終端的鍵盤
- 標準輸出(stdout)、標準錯誤輸出文件(stderr)都是對應終端的屏幕。進程從stdin獲取數(shù)據(jù)傳遞給stdout,如果有錯誤信息就傳遞給stderr
線程:是程序正在做的事情,線程是進程的單個控制流(比如360的殺毒,掃描木馬)
單線程:一個進程如果只有一條執(zhí)行路徑,則稱為單線程程序
多線程:一個進程如果有多條執(zhí)行路徑,則稱為多線程程序
進程與線程的區(qū)別:
- 進程:有獨立的內(nèi)存空間,進程中的數(shù)據(jù)存放空間(堆空間和棧空間)是獨立的,至少有一個線程。
- 線程:堆空間是共享的,棧空間是獨立的,線程消耗的資源比進程小的多。
多線程同時執(zhí)行原理:
比如我們同時運行qq和微信,其實不是同時運行的而是CPU在多個線程間快速切換,造成"同時"執(zhí)行的假象
多線程的好處:
- 可以"同時"執(zhí)行多個任務
- 可以提高資源的利用率(CPU/網(wǎng)絡)
線程越多越好嗎:
1.創(chuàng)建和銷毀線程需要消耗CPU和內(nèi)存資源
2.線程太多,CPU需要在大量的線程間切換,造成資源的浪費
進程與并發(fā):
在使用進程實現(xiàn)并發(fā)時會出現(xiàn)以下問題:
孤兒進程:
父進程比子進程先結束,子進程成為孤兒進程,子進程的父進程成為init進程,稱為init進程領養(yǎng)孤兒進程。
僵尸進程:
僵尸進程: 進程終止,父進程尚未回收,子進程殘留資源(PCB)存放于內(nèi)核中,變成僵尸(Zombie)進程。
Windows&Linux進程:
Windows下的進程和Linux下的進程是不一樣的,它比較懶惰,從來不執(zhí)行任何東西,只是為線程提供執(zhí)行環(huán)境。然后由線程負責執(zhí)行包含在進程的地址空間中的代碼。當創(chuàng)建一個進程的時候,操作系統(tǒng)會自動創(chuàng)建這個進程的第一個線程,成為主線程。
線程并發(fā):
- LWP:light weight process 輕量級的進程,本質(zhì)仍是進程 (Linux下)
- 進程:獨立地址空間,擁有PCB
- 線程:有獨立的PCB,但沒有獨立的地址空間(共享)
- 區(qū)別:在于是否共享地址空間。獨居(進程);合租(線程)。
- 線程:最小的執(zhí)行單位,線程可以提高程序的并發(fā)率
- 進程:最小分配資源單位,可看成是只有一個線程的進程。
- Windows系統(tǒng)下,可以直接忽略進程的概念,只談線程。因為線程是最小的執(zhí)行單位,是被系統(tǒng)獨立調(diào)度和分派的基本單位。而進程只是給線程提供執(zhí)行環(huán)境。
線程同步:
- 指一個線程發(fā)出某一功能調(diào)用時,在沒有得到結果之前,該調(diào)用不返回。同時其它線程為保證數(shù)據(jù)一致性,不能調(diào)用該功能。也就是一致性,和Sql里的事務一樣
- 同步的目的,是為了避免數(shù)據(jù)混亂,解決與時間有關的錯誤。實際上,不僅線程間需要同步,進程間、信號間等等都需要同步機制。因此,所有多個控制流,共同操作一個共享資源”的情況,都需要同步。
互斥量mutex:
- Linux中提供一把互斥鎖mutex(也稱之為互斥量),同一時刻只能有一個線程持有該鎖。每個線程在對資源操作前都嘗試先加鎖,成功加鎖才能操作,操作結束解鎖。資源還是共享的,線程間也還是競爭的,但通過“鎖”就將資源的訪問變成互斥操作,而后與時間有關的錯誤也不會再產(chǎn)生了。
- 當A線程對某個全局變量加鎖訪問,B在訪問前嘗試加鎖,拿不到鎖,B阻塞。C線程不去加鎖,而直接訪問該全局變量,依然能夠訪問,但會出現(xiàn)數(shù)據(jù)混亂。所以,互斥鎖實質(zhì)上是操作系統(tǒng)提供的一把建議鎖/協(xié)同鎖,建議程序中有多線程訪問共享資源的時候使用該機制。但,并沒有強制限定。因此,即使有了互斥鎖,如果有線程不按規(guī)則來訪問數(shù)據(jù),依然會造成數(shù)據(jù)混亂。
讀寫鎖:
與互斥量類似,但讀寫鎖允許更高的并行性,讀寫鎖只有一把
其特性為:寫獨占,讀共享
讀寫鎖狀態(tài):
讀寫鎖特性:
協(xié)程并發(fā):
協(xié)程:coroutine也叫輕量級線程。
- 與傳統(tǒng)的系統(tǒng)級線程和進程相比,協(xié)程最大的優(yōu)勢在于“輕量級”。可以輕松創(chuàng)建上萬個而不會導致系統(tǒng)資源衰竭。而線程和進程通常很難超過1萬個。這也是協(xié)程別稱“輕量級線程”的原因。
- 一個線程中可以有任意多個協(xié)程,但某一時刻只能有一個協(xié)程在運行,多個協(xié)程分享該線程分配到的計算機資源。
- 多數(shù)語言在語法層面并不直接支持協(xié)程,而是通過庫的方式支持,但用庫的方式支持的功能也并不完整,比如僅僅提供協(xié)程的創(chuàng)建、銷毀與切換等能力。如果在這樣的輕量級線程中調(diào)用一個同步 IO 操作,比如網(wǎng)絡通信、本地文件讀寫,都會阻塞其他的并發(fā)執(zhí)行輕量級線程,從而無法真正達到輕量級線程本身期望達到的目標。
- 在協(xié)程中,調(diào)用一個任務就像調(diào)用一個函數(shù)一樣,消耗的系統(tǒng)資源最少!但能達到進程、線程并發(fā)相同的效果。
- 在一次并發(fā)任務中,進程、線程、協(xié)程均可以實現(xiàn)。從系統(tǒng)資源消耗的角度出發(fā)來看,進程相當多,線程次之,協(xié)程最少。
總結
以上是生活随笔為你收集整理的并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 建模_Java设计模式菜鸟系列
- 下一篇: tomcat安装启动配置