隨著服務程序的增多,光憑程序內的執行緒同步已經不能滿足現在的需求,導致多程序同時寫入同乙個檔案時,一樣提示檔案被占用的問題。
在這種場景下,跨程序級的鎖是不可避免的。在.net提供的參考中,程序鎖都繼承了system.threading.waithandle類
。而在本文中針對單個檔案同一時間僅允許單個程序(執行緒)操作的場景,system.threading.mutex類
無疑是最簡單也是最合適的選擇。
該型別的物件可以使用命名(字串)互斥量實現當前會話級或作業系統級的同步需求。我選擇了作業系統級別的同步編寫示例,因為覆蓋面更廣。
namespacewaithandleexample
);#endregion
#region 測試**
test.log
").toupper();
var mutexkey =mutexexample.getfilepathmutexkey(filepath);
//同時開啟n個寫入執行緒
parallel.for(0, logcount, e =>);
});console.writeline(
string.format("
log count:.\t\twrited count:.\tfailed count:.
", logcount.tostring(), writedcount.tostring(), failedcount.tostring()));
console.read();
#endregion
}
//////
c#互斥量使用示例**
/// ///
已在經過測試並上線執行,可直接使用
public
static
class
mutexexample
finally}}
//////
獲取檔名對應的程序同步鍵
/// ///
檔案路徑(請注意大小寫及空格)
///程序同步鍵(互斥體名稱)
public
static
string getfilepathmutexkey(string
filepath)
", filepath)));
//轉換為作業系統級的同步鍵
var mutexkey = string.format(@"
global\
", filekey);
return
mutexkey;
}//////
程序間同步執行
/// ///
作業系統級的同步鍵
///(如果將 name 指定為 null 或空字串,則建立乙個區域性互斥體。
///如果名稱以字首「global\」開頭,則 mutex 在所有終端伺服器會話中均為可見。
///如果名稱以字首「local\」開頭,則 mutex 僅在建立它的終端伺服器會話中可見。
///如果建立已命名 mutex 時不指定字首,則它將採用字首「local\」。)
///同步處理操作
public
static
void mutexexec(string
mutexkey, action action)
//////
程序間同步執行
/// ///
作業系統級的同步鍵
///(如果將 name 指定為 null 或空字串,則建立乙個區域性互斥體。
///如果名稱以字首「global\」開頭,則 mutex 在所有終端伺服器會話中均為可見。
///如果名稱以字首「local\」開頭,則 mutex 僅在建立它的終端伺服器會話中可見。
///如果建立已命名 mutex 時不指定字首,則它將採用字首「local\」。)
///同步處理操作
///指示當前呼叫是否為遞迴處理,遞迴處理時檢測到異常則丟擲異常,避免進入無限遞迴
private
static
void mutexexec(string mutexkey, action action, bool
recursive)
//當其他程序已上鎖且沒有正常釋放互斥鎖時(譬如程序忽然關閉或退出),則會丟擲abandonedmutexexception異常
catch
(abandonedmutexexception ex)
finally}}
}#region 測試寫檔案的**
測試結果:6個程序同時進行3000次寫入請求,僅成功寫入277次
測試結果:6個程序同時進行3000次寫入請求,全部成功寫入
程序同步的資源消耗及效率比執行緒同步要差得多,請根據實際場景合理使用。
本文雖然是用寫入檔案作為示例,但程序同步的**使用場景與檔案操作無關。
semaphore類(訊號燈)雖然可以限制同時操作的執行緒數,甚至把最大同時運算元設定為1時,行為與mutex類(互斥量)類似;但是由於訊號燈在其他程序中出現異常退出時並不能接收到異常通知,只能通過等待超時觸發異常,並不適合現在的場景,所以並沒講述。
關於程序同步的其他深入了解及應用,請參閱其他資料。
多程序讀寫鎖
多程序程式設計的核心技術是程序間的同步 通訊與互斥訪問 一 程序間的通訊 1 管道 2 system v訊號量 3 共享記憶體 4 訊息佇列 5 訊號 6 套接字 二 程序間對資源的互斥訪問 條件變數 訊號量讀寫鎖 記錄鎖 自旋鎖原子鎖 順序鎖 記錄鎖 int fcntl int fd,int cm...
多程序中的程序鎖(互斥鎖)
以下例項中 import threading lock threading.lock num 0def work1 asd global num for i in range asd num 1print 在當前的執行緒修改過後的num是 num defwork2 asd global num fo...
Linux C 多程序檔案操作之檔案鎖
flock函式可以鎖定檔案,避免多個程序對同個檔案進行操作時出現資料出錯。flock的用法是在開啟檔案後對檔案讀寫前呼叫flock函式上鎖,檔案操作完後flock解鎖,但需注意另乙個程序操作同個檔案時必須自己去檢查檔案是否已上鎖,即在讀寫檔案前呼叫flock函式即可進行判斷,如果上鎖,該程序則會阻塞...