天天看點

線程與信号,線程與鎖

線程内互相排斥快的原因:

    線程的全部資源都線上程空間内。尋址僅僅在本線程内部

    程序的消息隊列和共享記憶體會被線程採用==>共享記憶體最大長處:獨立于全部程序

    當程式出錯時。共享記憶體會中的資料會儲存在記憶體中。重新啟動後會恢複執行狀态。

    消息隊列:獨立程序和線程,消息必定會被接收而且會被處理(除非是流水線

    作業式)自己能夠傳回。

接收到消息的線程和程序挨個運作受到消息的處理程式

    多任務優勢:同一時候執行核心處理——單核分時處理

    線程的生命不獨立

程序比線程慢的原因:

    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個資源。

信号量、消息隊列和共享記憶體的差别:

    @信号量、消息隊列是調用系統調用完畢,

    @共享記憶體僅僅是在申請時調用系統調用。之後都在自己的程序區間内

     通過指針進行操作。效率比較高。