C 執行緒同步

2022-06-09 12:21:05 字數 3632 閱讀 6776

同步就是協同步調,按預定的先後次序進行執行。如:你說完,我再說。

如程序、執行緒同步,可理解為程序或執行緒a和b一塊配合,a執行到一定程度時要依靠b的某個結果,於是停下來,示意b執行;b依言執行,再將結果給a;a再繼續操作。

這裡的同步千萬不要理解成那個同時進行,應是指協同、協助、互相配合。執行緒同步是指多執行緒通過特定的設定(如互斥量,事件物件,臨界區)來控制線程之間的執行順序(即所謂的同步)

在多執行緒程式設計裡面,一些敏感資料不允許被多個執行緒同時訪問,此時就使用同步訪問技術,保證資料在任何時刻,最多有乙個執行緒訪問,以保證資料的完整性。

執行緒互斥是指對於共享的程序系統資源,在各單個執行緒訪問時的排它性。當有若干個執行緒都要使用某一共享資源時,任何時刻最多隻允許乙個執行緒去使用,其它要使用該資源的執行緒必須等待,

直到占用資源者釋放該資源。執行緒互斥可以看成是一種特殊的執行緒同步(下文統稱為同步)。

如果有多個執行緒同時訪問共享資料的時候,就必須要用執行緒同步,防止共享資料被破壞。如果多個執行緒不會同時訪問共享資料,可以不用執行緒同步。

執行緒同步也會有一些問題存在:

1、效能損耗。獲取,釋放鎖,執行緒上下文的切換都是耗效能的。

2、同步會使執行緒排隊等待執行。

臨界區(critical section)、互斥物件(mutex):主要用於互斥控制;都具有擁有權的控制方法,只有擁有該物件的執行緒才能執行任務,所以執行完任務後一定要釋放該物件。

訊號量(semaphore)、事件物件(event):事件物件是以通知的方式進行控制,主要用於同步控制!

加鎖使多個執行緒同一時間只有乙個執行緒可以呼叫該方法,其他執行緒被阻塞。

同步物件的選擇:

1、使用引用型別,值型別加鎖時會裝箱,產生乙個新的物件。

2、使用private修飾,使用public時易產生死鎖。(使用lock(this),lock(typeof(例項))時,該類也應該是private)。

3、string不能作為鎖物件。

4、不能在lock中使用await關鍵字

5、如果這個鎖是靜態型別。這樣就是在全域性鎖定了該方法,不管該類有多少個例項,都要排隊執行。

6、如果不使用靜態型別的鎖,因為被鎖定的方法是屬於例項的,只要該例項呼叫鎖定方法不產生損壞就可以,不同例項間是不需要鎖的。這個鎖只鎖該例項的方法,而不是鎖所有例項的方法.*

class

threadsafe

}private

object _locker2 = new

object

();void

goto()

}

1.併發:在作業系統中,是指乙個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同乙個處理機上執行。其中兩種併發關係分別是同步和互斥

2.互斥:程序間相互排斥的使用臨界資源的現象,就叫互斥。

3.同步:程序之間的關係不是相互排斥臨界資源的關係,而是相互依賴的關係。進一步的說明:就是前乙個程序的輸出作為後乙個程序的輸入,當第乙個程序沒有輸出時第二個程序必須等待。具有同步關係的一組併發程序相互傳送的資訊稱為訊息或事件。其中併發又有偽併發和真併發,偽併發是指單核處理器的併發,真併發是指多核處理器的併發。

4.並行:在單處理器中多道程式設計系統中,程序被交替執行,表現出一種併發的外部特種;在多處理器系統中,程序不僅可以交替執行,而且可以重疊執行。在多處理器上的程式才可實現並行處理。從而可知,並行是針對多處理器而言的。並行是同時發生的多個併發事件,具有併發的含義,但併發不一定並行,也亦是說併發事件之間不一定要同一時刻發生。

5.多執行緒:多執行緒是程式設計的邏輯層概念,它是程序中併發執行的一段**。多執行緒可以實現執行緒間的切換執行。

6.非同步:非同步和同步是相對的,同步就是順序執行,執行完乙個再執行下乙個,需要等待、協調執行。非同步就是彼此獨立,在等待某事件的過程中繼續做自己的事,不需要等待這一事件完成後再工作。執行緒就是實現非同步的乙個方式。非同步是讓呼叫方法的主線程不需要同步等待另一線程的完成,從而可以讓主線程幹其它的事情。

非同步和多執行緒並不是乙個同等關係,非同步是最終目的,多執行緒只是我們實現非同步的一種手段。非同步是當乙個呼叫請求傳送給被呼叫者,而呼叫者不用等待其結果的返回而可以做其它的事情。實現非同步可以採用多執行緒技術或則交給另外的程序來處理。

為了對以上概念的更好理解舉乙個簡單例子, 

假設我要做 燒開水,舉槓鈴100下, 洗衣服 3件事情。

燒開水 這件事情, 我要做的事情為, 準備燒開水 1分鐘, 等開水燒開 8 分鐘 , 關掉燒水機 1分鐘

舉槓鈴100下 我要做的事情為, 舉槓鈴100下 10分鐘

洗衣服 我要做的事情為, 準備洗衣服 1分鐘, 等衣服洗完 5 分鐘 , 關掉洗衣機 1分鐘

單核情況下

同步的完成,我需要做的時間為 1+ 8 +1 + 10 + 1+ 5 +1 = 27 分

如果非同步,就是在等的時候,我可以切換去做別的事情

準備燒開水(1) + 準備洗衣服(1) + 舉50下槓鈴 (5)分鐘 + 關洗衣機(1)分鐘 + 舉槓鈴20下 (2)分鐘 + 關燒水機(1)分鐘 + 舉30下槓鈴(3)分鐘

1+1+5+1+2+1+3 =14 分鐘

雙核 非同步 並行

核1 準備燒開水 1分鐘 + 舉槓鈴50下(5)分鐘 + 等待3分鐘 + 關掉燒水機 1分鐘

核2 準備洗衣服 1分鐘 + 舉槓鈴50下(5)分鐘 + 關掉洗衣機 1分鐘 + 等待3分鐘

其實只花了 1+5+3+1 = 10分鐘

其中還有雙核都等待了3分鐘

雙核 非同步 非並行

核1 舉槓鈴100下(10)分鐘

核2 準備燒開水 1分鐘 + 準備洗衣服 1分鐘 + 等待5 分鐘 + 關掉洗衣機 1分鐘 + 等待 1 分鐘 + 關掉燒水機 1分鐘

其實只花了 1+1+5+1+1+1 = 10分鐘

多執行緒的做法

單核下執行緒1 準備燒開水 1分鐘, 等開水燒開 8 分鐘 , 關掉燒水機 1分鐘

執行緒2 舉槓鈴100下 10分鐘

執行緒3 準備洗衣服 1分鐘, 等開水燒開 5 分鐘 , 關掉洗衣機 1分鐘

cpu 可能這麼切換 最理想的切換方式

執行緒1 準備燒開水1 sleep 1 sleep 5 sleep 1 sleep 2 關開水 1分鐘 exit

執行緒2 sleep 1 sleep 1 舉槓鈴50 5分鐘 sleep 1 舉槓鈴20 2分鐘 sleep1 舉槓鈴30下 3分鐘 

執行緒3 sleep 1 準備洗衣服1 分鐘 sleep 5 關洗衣機1分鐘 exit

最後使用了 14分鐘 和 單核非同步是一樣的。

但是實際上是不一樣的,因為執行緒不會按照我們設想的去跑, 如果執行緒2 舉槓鈴先跑,整個流程的速度就下來了。

非同步和同步的區別, 在io等待的時候,同步不會切走,浪費了時間。

如果都是獨佔cpu 的業務, 比如舉槓鈴的業務, 在單核情況下 多線和單線 沒有區別。

多執行緒的好處是比較容易的實現了非同步切換的思想, 因為非同步的程式很難寫的。

多執行緒本身還是以同步完成,但是應該說比效率是比不上非同步的。 而且多線很容易寫, 相對效率也高。

多核的好處,就是可以同時做事情, 這個和單核完全不一樣的。

C 執行緒同步

volatile是最簡單的一種同步方法,當然簡單是要付出代價的。它只能在變數一級做同步,volatile的含義就是告訴處理器,不要將我放入工作記憶體,請直接在主存操作我。www.bitscn.com 因此,當多執行緒同時訪問該變數時,都將直接操作主存,從本質上做到了變數共享。能夠被標識為volati...

c 執行緒同步

以乙個程式來說明執行緒不同步所帶來的問題 class program private int counter 0 private void actionmethod t thread.currentthread.name,counter 結果如下 從上面的結果中可以看到主線程和子執行緒都在爭奪act...

C 執行緒同步

使用mutex類來同步兩個單獨的程式。mutex是一種原始的同步方式,其只對乙個執行緒授予對共享資源的獨佔訪問。const string nutexname c using var m new mutex false nutexname else 互斥量是全域性的作業系統物件,請務必正確關閉互斥量。...