1. 前言
實現同一個進程中不同線程之間的通信是比較容易的,因為不同線程在內存中共享同一個內存地址,數據也是可以共享的。而進程則不同,不同的進程在內存中擁有獨立的地址空間,要想實現進程間的通信就必須建立不同進程都可以訪問的共享內存。C#在命名空間ystem.Threading下提供了一個類Mutex 來實現跨進程資源的訪問。
1)場景建立
假設有A和B兩個環境,環境A中存在一個對象a,環境B中存在一個對象b,我們的目的是實現對象a和對象b的同步,對象a和b一個版本號version的屬性,如果它們的版本號a-version和b-version相同則可判斷二者已同步。為此開發兩個同步程序ProgressAtoB和ProgressBtoA,當對象a發生變化時調用ProgressAtoB去更新b,當對象b發生變化時調用ProgressBtoA去更新a,如下圖所示:
ProgressAtoB執行的操作如下:
ProgressBtoA執行的操作如下:
2)運行ProgressAtoB和ProgressBtoA
某一時刻的運行結果如下:
根據運行結果我們可以分析得出ProgressAtoB和ProgressBtoA兩個進程的運行是交替進行的而且沒有一定的時序。這種現象是有兩個原因造成的:1.兩個進程何時發生切換是由CPU調度實現的,時間是不確定的。2.進程中的操作不具備原子性。
如果ProgressAtoB進程在未更新版本號之前切換到了ProgressBtoA,ProgressBtoA檢測到版本號還是舊的(因為ProgressAtoB還沒有對版本號進行更新就切換到了ProgressBtoA)就會重復去更新對象a,這樣導致了a的重復更新,甚至會導致對象a和b的循環更新。
3)引入Mutex
ProgressAtoB執行的操作如下:
ProgressBtoA執行的操作如下:
某一時刻的運行結果如下:
對運行結果分析可知:進程ProgressAtoB在執行時不會切換到進程ProgressBtoA,同樣
進程ProgressBtoA在執行時不會切換到進程ProgressAtoB,這樣就保證了操作的完整性,避免了重復更新和循環更新的問題。