執行緒篇 執行緒間同步之訊號量 互斥鎖

2021-09-25 22:13:12 字數 2097 閱讀 5148

執行緒:程序內部的一條執行路徑(序列)

什麼是執行緒什麼是程序,程序和執行緒的區別?

程序是乙個正在執行的程式,是系統程序資源分配的基本單位

執行緒是程序內部的一條執行路徑,是系統排程的基本單位

pthread.h標頭檔案  -lpthread 庫

理解多執行緒的併發執行?

併發執行:單個或多個處理器

並行:需要多處理器

執行緒同步(執行緒間通訊):訊號量,互斥鎖,條件變數,讀寫鎖

訊號量和互斥鎖區別?

mutex,互斥鎖,用於序列化對一部分可重入**的訪問,這些**不能由多個執行緒同時執行

semaphore,訊號量,將共享資源的併發使用者數限制為最大數量

互斥鎖:主要解決互斥性問題,相當於乙個初值為1的二值訊號量,更方便

mutex:假設我們有關鍵部分執行緒t1想要訪問它然後它遵循以下步驟:

1.鎖2.使用關鍵部分

3.開鎖

二進位制訊號量:它基於信令等待和訊號工作。等待(s)將「s」值減少乙個通常「s」值用值「1」初始化,訊號(s)將「s」值增加1。如果「s」值為1表示沒有人使用臨界區,則值為0表示臨界區正在使用中。假設執行緒t2正在使用臨界區,那麼它遵循以下步驟:

1.wait(s)//最初s值在呼叫之後等於它的值減1,即0

2.使用關鍵部分

3.signal(s)//現在s值增加,變為1

自旋鎖:核心中同步時使用的,忙等待的鎖

對於互斥鎖,如果資源已經被占用,資源申請者只能進入睡眠狀態;自旋鎖不會引起呼叫者睡眠,如果自旋鎖已經被別的執行單元保持,呼叫者就一直迴圈在那裡看是否該自旋鎖的保持者已經釋放了鎖。

自旋鎖的缺陷:1.死鎖2.過多占用cpu資源

忙等待的鎖:一直占用cpu進行測試,需要多處理器

非忙等待的鎖:處於阻塞等待

無鎖佇列:

cas(c++)compare and set:乙個安全檢查

cas是解決多執行緒並**況下使用鎖造成效能損耗的一種機制

記憶體位置(v)、預期原值(a)、新值(b):如果記憶體位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新為新值。

1.無鎖同步cas:

當我們如果只是由於一條**出現了執行緒安全問題,比如說多個執行緒都要往乙個佇列中的尾部插入乙個元素,那麼我們的tail->next=newnode;是我們一條必要的**。但是當我們拿到tail的時候,在執行這條指令前,其他執行緒率先在原來的佇列尾部插入元素,這就會引起tail的失效,因為tail的值變了。這種情況下如果我們加入了鎖只是為了控制一條臨界**,那麼開銷就太大了。因此我們就引入了我們cpu的cas操作。

2.我們將cas用在佇列當中構造乙個無鎖佇列來說明以上cas的具體用途

enqueue(x) //進佇列q

while( !cas(p->next, null, q));//如果沒有把結點鏈在尾指標上,再試

如果p->next == null 則 p->next = q;其他執行緒也進不來

cas(tail, p, q);//置尾結點

看尾是不是p,是則更新tail = q,讓其他執行緒可以進來 }

dequeue() //出佇列

while( !cas(head, p, p->next));

return p->next->value;

}cas缺點:

1.存在aba問題因為cas需要在操作值的時候檢查下值有沒有發生變化,如果沒有發生變化則更新,但是如果乙個值原來是a,變成了b,又變成了a,那麼使用cas進行檢查時會發現它的值沒有發生變化,但是實際上卻變化了。aba問題的解決思路就是使用版本號。在變數前面追加上版本號,每次變數更新的時候把版本號加一,那麼a-b-a 就會變成1a-2b-3a。

2.迴圈時間長開銷大自旋cas如果長時間不成功,會給cpu帶來非常大的執行開銷。

3. 只能保證乙個共享變數的原子操作對乙個共享變數執行操作時,我們可以使用迴圈cas的方式來保證原子操作,但是對多個共享變數操作時,迴圈cas就無法保證操作的原子性,這個時候就可以用鎖,或者有乙個取巧的辦法,就是把多個共享變數合併成乙個共享變數來操作。比如有兩個共享變數i=2,j=a,合併一下ij=2a,然後用cas來操作ij。

執行緒互斥與同步 互斥鎖與訊號量

所謂互斥,就是不同執行緒通過競爭進入臨界區 共享的資料和硬體資源 為了防止訪問衝突,在有限的時間內只允許其中之一獨占性的使用共享資源。如不允許同時寫 同步關係則是多個執行緒彼此合作,通過一定的邏輯關係來共同完成乙個任務。一般來說,同步關係中往往包含互斥,同時對臨界區的資源會按照某種邏輯順序進行訪問。...

Linux執行緒 執行緒同步互斥 訊號量

從概念上來說,訊號量是乙個非負整數計數。訊號量通常用來協調對資源的訪問,其 中訊號計數會初始化為可用資源的數目。然後,執行緒在資源增加時會增加計數,在刪 除資源時會減小計數,這些操作都以原子方式執行。如果訊號計數變為零,則表明已無可用資源。計數為零時,嘗試減小訊號的執行緒會被 阻塞,直到計數大於零為...

linux 執行緒互斥同步By訊號量

今天有空就研究了下linux執行緒間的同步通訊by訊號量,離校錢只是匆匆的從網上看了一點概念性的東西 其實連概念也談不上,就知道有訊號量這麼回事 對於具體的怎麼用 實現也不知道,現在正好有時間,研究了一下。sem t include int sem init sem t sem,int pshare...