一、python中的文件鎖
我們在寫python應用的時候,當涉及到多個進程向同一個文件write(或者read)的情況,如果幾個進程同時都對這個文件進行寫操作,那么文件的內容就會變得非常混亂,這個時候文件鎖就派上用場了。
python中的文件鎖,可以保證同時只有一個進程寫文件,目前使用的是fcntl這個庫,它實際上為 Unix上的ioctl,flock和fcntl 函數提供了一個接口。python通過調用fcntl.flock()函數對文件加鎖。
fcntl這個模塊是Python自帶的,但Windows沒有,可以手工下載fcntl.py文件,然后保存到python的Lib目錄下。
二、鎖類型
- LOCK_SH: 表示要創建一個共享鎖,在任意時間內,一個文件的共享鎖可以被多個進程擁有
- LOCK_EX: 表示創建一個排他鎖,在任意時間內,一個文件的排他鎖只能被一個進程擁有
- LOCK_UN: 表示刪除該進程創建的鎖(解鎖)
- LOCK_MAND:它主要是用於共享模式強制鎖,它可以與 LOCK_READ 或者 LOCK_WRITE 聯合起來使用,從而 表示是否允許並發的讀操作或者並發的寫操作(盡管在 flock() 的手冊頁中沒有介紹 LOCK_MAND,但是閱讀內核源代碼就會發現,這在內核中已經實現了)
- LOCK_NB: 如果指定此參數,函數不能獲得文件鎖就立即返回,否則,函數會等待獲得文件鎖。LOCK_NB可以同LOCK_SH或LOCK_EX進行按位或(|)運算操作。
例如:一個文件設置了排它鎖,如果這個鎖已經被某個進程獲取了,那么其他進程請求獲取這個鎖的時候將會被阻塞。
如果想要在沒有獲得這個排他鎖的情況下不阻塞那些進程,可以與 LOCK_NB 聯合使用,那么系統就不會阻塞該進程。即: fcnt.flock(f,fcntl.LOCK_EX|fcntl.LOCK_NB)
三、注意點
- 對於文件的 close() 操作會使文件鎖失效;
- 同理,進程結束后文件鎖失效;
- flock() 的 LOCK_EX是“勸告鎖”,系統內核不會強制檢查鎖的狀態,需要在代碼中進行文件操作的地方顯式檢查才能生效。
- 在給文件加鎖之前,一定要保證文件以相應的訪問模式打開,例如:
要對一個文件加上共享鎖,一定要首先按讀模式打開文件;
若要給文件加上排他鎖,則首先要按寫模式打開對應文件;
若想加兩種鎖,則需要按讀寫模式打開.
四、示例
import fcntl class Lock(object): def __init__(self, file_name): self.file_name = file_name self.handle = open(file_name, 'w+') def lock(self): fcntl.flock(self.handle, fcntl.LOCK_EX | fcntl.LOCK_NB) def unlock(self): fcntl.flock(self.handle, fcntl.LOCK_UN) def __del__(self): try: self.handle.close() except: pass