一、進(jìn)程與線程的區(qū)別:
1、進(jìn)程是資源分配的最小單位,線程是程序執(zhí)行的最小單位(資源調(diào)度的最小單位)
2、進(jìn)程有自己的獨(dú)立地址空間,每啟動一個進(jìn)程,系統(tǒng)就會為它分配地址空間,建立數(shù)據(jù)表來維護(hù)代碼段、堆棧段和數(shù)據(jù)段,這種操作非常昂貴。
而線程是共享進(jìn)程中的數(shù)據(jù)的,使用相同的地址空間,因此CPU切換一個線程的花費(fèi)遠(yuǎn)比進(jìn)程要小很多,同時創(chuàng)建一個線程的開銷也比進(jìn)程要小很多。
3、線程之間的通信更方便,同一進(jìn)程下的線程共享全局變量、靜態(tài)變量等數(shù)據(jù),而進(jìn)程之間的通信需要以通信的方式(IPC)進(jìn)行。不過如何處理好同步與互斥是編寫多線程程序的難點(diǎn)。
4、但是多進(jìn)程程序更健壯,多線程程序只要有一個線程死掉,整個進(jìn)程也死掉了,而一個進(jìn)程死掉并不會對另外一個進(jìn)程造成影響,因?yàn)檫M(jìn)程有自己獨(dú)立的地址空間。
參考:https://www.cnblogs.com/zhehan54/p/6130030.html
二、進(jìn)程與線程的資源:
1、堆與棧
堆: 是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統(tǒng)對進(jìn)程初始化的時候分配,運(yùn)行過程中也可以向系統(tǒng)要額外的堆,但是記得用完了要還給操作系統(tǒng),要不然就是內(nèi)存泄漏。
棧:是個線程獨(dú)有的,保存其運(yùn)行狀態(tài)和局部自動變量的。棧在線程開始的時候初始化,每個線程的?;ハ嗒?dú)立,因此,棧是 thread safe的。操作系統(tǒng)在切換線程的時候會自動的切換棧,就是切換?。樱樱牛樱屑拇嫫鳌?臻g不需要在高級語言里面顯式的分配和釋放。
2、其他
線程共享的環(huán)境包括:進(jìn)程代碼段、進(jìn)程的公有數(shù)據(jù)(利用這些共享的數(shù)據(jù),線程很容易的實(shí)現(xiàn)相互之間的通訊)、進(jìn)程打開的文件描述符、信號的處理器、進(jìn)程的當(dāng)前目錄和進(jìn)程用戶ID與進(jìn)程組ID。
進(jìn)程擁有這許多共性的同時,還擁有自己的個性。有了這些個性,線程才能實(shí)現(xiàn)并發(fā)性。這些個性包括:
1.線程ID
每個線程都有自己的線程ID,這個ID在本進(jìn)程中是唯一的。進(jìn)程用此來標(biāo)
識線程。
2.寄存器組的值
由于線程間是并發(fā)運(yùn)行的,每個線程有自己不同的運(yùn)行線索,當(dāng)從一個線
程切換到另一個線程上時,必須將原有的線程的寄存器集合的狀態(tài)保存,以便
將來該線程在被重新切換到時能得以恢復(fù)。
3.線程的堆棧
堆棧是保證線程獨(dú)立運(yùn)行所必須的。
線程函數(shù)可以調(diào)用函數(shù),而被調(diào)用函數(shù)中又是可以層層嵌套的,所以線程
必須擁有自己的函數(shù)堆棧,使得函數(shù)調(diào)用可以正常執(zhí)行,不受其他線程的影
響。
4.錯誤返回碼
由于同一個進(jìn)程中有很多個線程在同時運(yùn)行,可能某個線程進(jìn)行系統(tǒng)調(diào)用
后設(shè)置了errno值,而在該線程還沒有處理這個錯誤,另外一個線程就在此時
被調(diào)度器投入運(yùn)行,這樣錯誤值就有可能被修改。
所以,不同的線程應(yīng)該擁有自己的錯誤返回碼變量。
5.線程的信號屏蔽碼
由于每個線程所感興趣的信號不同,所以線程的信號屏蔽碼應(yīng)該由線程自
己管理。但所有的線程都共享同樣的信號處理器。
6.線程的優(yōu)先級
由于線程需要像進(jìn)程那樣能夠被調(diào)度,那么就必須要有可供調(diào)度使用的參
數(shù),這個參數(shù)就是線程的優(yōu)先級。
參考:https://blog.csdn.net/shuilan0066/article/details/7683315
3、進(jìn)程與線程的同步
進(jìn)程:無名管道、有名管道、信號、共享內(nèi)存、消息隊列、信號量
進(jìn)程:互斥量、讀寫鎖、自旋鎖、線程信號、條件變量