進程是正在執(zhí)行的程序,是資源分配的基本單位。
線程是進程內(nèi)部的不同執(zhí)行路徑,是資源進行調(diào)度的基本單位,一個進程有多個線程,它們共享進程資源。
進程和線程都要各自的生命周期以及通信方式。
進程是資源分配的基本單位,但是線程不擁有資源,線程可以訪問隸屬于進程的資源。
線程是調(diào)度的基本單位,在同一進程中,線程的切換并不會引起進程的切換。一個進程的線程切換到不同進程的線程會引起進程的切換。
在創(chuàng)建,銷毀以及切換進程時所帶來的消耗遠遠大于線程的創(chuàng)建,銷毀以及切換。
進程和線程的應(yīng)用場景
進程是資源分配的基本單位,線程是資源調(diào)度的基本單位。
屬于同一進程的線程,堆是共享的,棧是私有的。且所有的線程都具有連續(xù)的地址空間。
- 多進程的優(yōu)點
內(nèi)存隔離,可以盡量減少線程加鎖/釋放鎖所帶來的消耗
每個進程相對獨立,子進程的奔潰并不會影響到主進程。 - 多進程缺點
進程間的調(diào)用,通訊,切換所帶來的消耗均比多線程大。 - 多進程使用場景
如果目標子功能交互少,以及資源允許可以采用多進程方式。 - 多線程優(yōu)點
無須跨越進程邊界,并且多個線程可以直接共享進程內(nèi)存與變量等,多線程所帶來的消耗較小。 - 多線程缺點
并沒有內(nèi)存隔離,線程之間的同步和加鎖比較麻煩。單個線程的奔潰很有可能影響到整個程序。
一般來說,頻繁的任務(wù)創(chuàng)建,銷毀并且切換以及大量計算任務(wù)優(yōu)先使用多線程。
孤兒進程、僵尸進程與守護進程
孤兒進程就是說一個父進程退出,而它的一個或多個子進程還在運行,那么這些子進程將成為孤兒進程。孤兒進程將被 init 進程(進程ID為1的進程)所收養(yǎng),并由 init 進程對它們完成狀態(tài)收集工作。因為孤兒進程會被 init 進程收養(yǎng),所以孤兒進程不會對系統(tǒng)造成危害。
僵尸進程就是一個子進程的進程描述符在子進程退出時不會釋放,只有當(dāng)父進程通過 wait() 或 waitpid() 獲取了子進程信息后才會釋放。如果子進程退出,而父進程并沒有調(diào)用 wait() 或 waitpid(),那么子進程的進程描述符仍然保存在系統(tǒng)中,這種進程稱之為僵尸進程。僵尸進程通過 ps 命令顯示出來的狀態(tài)為 Z。
系統(tǒng)所能使用的進程號是有限的,如果產(chǎn)生大量僵尸進程,可能會因為沒有可用的進程號而導(dǎo)致系統(tǒng)不能產(chǎn)生新的進程。如果要消滅系統(tǒng)中大量的僵尸進程,只需要將其父進程殺死,此時僵尸進程就會變成孤兒進程,從而被 init 進程所收養(yǎng),這樣 init 進程就會釋放所有的僵尸進程所占有的資源,從而結(jié)束僵尸進程。
守護進程是運行在后臺的一種特殊進程,它是獨立于控制終端的,并周期性地執(zhí)行某些任務(wù)。
進程間同步方式
- 臨界區(qū)
臨界區(qū)是一段代碼,在臨界區(qū)內(nèi)進程將訪問臨界資源。任何時候最多只有一個進程可以進入臨界區(qū)。
優(yōu)點:保證在某一時刻只有一個線程能訪問數(shù)據(jù)的簡便辦法
缺點:雖然臨界區(qū)同步速度很快,但卻只能用來同步本進程內(nèi)的線程,而不可用來同步多個進程中的線程。
- 互斥量
就是使用一個互斥的變量來直接制約多個進程,互斥對象只有一個,只有擁有互斥對象的線程才具有訪問資源的權(quán)限。
優(yōu)點:可以實現(xiàn)不同進程的線程對資源的安全共享。
缺點:比臨界區(qū)帶來更多資源消耗,只能控制一個線程訪問該資源。
- 信號量
信號量相當(dāng)于一個計數(shù)器,它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數(shù)目?;コ饬渴切盘柫康囊环N特殊情況,當(dāng)信號量的最大資源數(shù)=1就是互斥量了。
缺點:信號量機制必須有公共內(nèi)存,不能用于分布式操作系統(tǒng),這是它最大的弱點。
- 事件機制
允許一個線程在處理完一個任務(wù)后,主動喚醒另外一個線程執(zhí)行任務(wù)
線程間的同步方式
- synchronize
- volatile
- reentrantlock
- threadLocal:每個線程都創(chuàng)建一個資源的副本,互相獨立互不影響
- automic 原子類
進程的內(nèi)存布局
文本段:記錄程序執(zhí)行的指令等等
初始化數(shù)據(jù)段:包含了初始化的全局變量
未初始化數(shù)據(jù)段:沒有包含初始化的全局變量
棧段
堆段