線程内互相排斥快的原因:
線程的全部資源都線上程空間内。尋址僅僅在本線程内部
程序的消息隊列和共享記憶體會被線程採用==>共享記憶體最大長處:獨立于全部程序
當程式出錯時。共享記憶體會中的資料會儲存在記憶體中。重新啟動後會恢複執行狀态。
消息隊列:獨立程序和線程,消息必定會被接收而且會被處理(除非是流水線
作業式)自己能夠傳回。
接收到消息的線程和程序挨個運作受到消息的處理程式
多任務優勢:同一時候執行核心處理——單核分時處理
線程的生命不獨立
程序比線程慢的原因:
1)程序空間獨立。須要核心作為中轉
2)線程在同一程序空間内,尋址記憶體連續,全部資源在同一程序區間
CUP核心使用率超過100%的原因:
多核處理。每一個CPU的使用率相加則使用率超過100%
線程同步:互相排斥
互相排斥量的種類:
互相排斥量 = 線程鎖 = mutex
線程鎖,讀寫鎖,自旋鎖,條件變量 <==> 線程同步的方式
@線程鎖子類:1)普通鎖 2)預設鎖 3)快速鎖 4)錯誤校驗鎖 5)回環鎖
鎖用來異步
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
若已經堵塞的條件下調用pthread_mutex_trylock。則會失敗,不能鎖住互相排斥量
傳回EBUSY。調用該函數防止死鎖。
@線程鎖堆的初始化
有鎖就有線程。鎖是為線程準備的。
若不初始化。則鎖為上鎖狀态,無法使用。
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
初始化的兩種方式:
1)動态:int pthread_mutex_init
2)靜态:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
若初始化為預設屬性,則attr置值為NULL;
若對靜态配置設定互相排斥量,則把它置為常量PTHREAD_MUTEX_INITIALIZER
@線程鎖的使用:先加鎖。再使用,再解鎖。
@以前擁有鎖的人解鎖後不sleep的情況下再次擁有鎖的機會更大;若解鎖後睡眠,
則再次搶到鎖的機會就均勻了。
有sleep時,延長了持鎖人持鎖的時間。本質上是别的線程有了等待的時機。
導緻持鎖人解鎖之後再次持鎖的時間變短了。
@10秒内檢測是否死鎖:
gdb中bt參數檢視棧幀,檢視方法:
1)檢視程序号 a) gdb attach id(程序号)
b) gdb -pid=id(程序号)
2)bt檢視棧幀
3)檢視程序棧幀局部變量的值
info threads
4)切換程序 thread Id(程序号)
5)檢視棧空間 bt full
6)退出程序調試 detach
7)退出gdb q
@一般說的線程鎖是指預設鎖,僅僅能加鎖一次。回環鎖為特殊的線程鎖。
能夠多次加鎖,一般用不到。
@自旋鎖的屬性
自旋鎖:假設自旋鎖已經被别的運作單元保持,調用者就一直循環檢視是否該
自旋鎖的保持已經釋放了鎖,“自旋”就是循環檢視的意思。
@回環鎖能夠多次加鎖,每加一次計數器加一。減鎖使用時。每減一次計數器減一
@1)盡量避免多鎖穿插使用
2)降低鎖的分支
3)線程鎖必須在全部函數使用之前聲明。相當于全局變量
4)全局變量實作互相排斥,不能代替鎖。全局變量不是原子的盡量不要用全局變量
替代鎖
@盡可能縮短臨界區的長度,避免第二次加鎖導緻程式被挂起(死鎖)
而不能異步互相排斥串行
@加鎖的目的就是實作異步互相排斥串行
@不用鎖的方法:将資源擴充,使互相排斥的對象變多。
如:10個線程相應10個資源。
信号量、消息隊列和共享記憶體的差别:
@信号量、消息隊列是調用系統調用完畢,
@共享記憶體僅僅是在申請時調用系統調用。之後都在自己的程序區間内
通過指針進行操作。效率比較高。