最近工作當中做了一個項目,這個項目主要是操作文件的。
在操作耗時操作的時候,我們一般采用多線程或者多進程。在開發中,如果多個線程需要對文件進行讀寫操作,就需要用到線程鎖或者是文件鎖。
使用fcntl
在Linux下,Python的標准庫有線程的文件鎖,來自fcntl模塊。這個模塊提供了Unix系統fcntl()和ioctl()的接口。
對於文件鎖的操作,主要需要使用fcntl.flock(fd,operation)這個函數。
其中,參數fd表示文件描述符;參數operation指定要進行的鎖操作,該參數的取值有如下幾種:
- LOCK_SH:表示要穿件一個共享鎖,在任意時間內,一個文件的共享鎖可以被多個進程擁有。
- LOCK_EX:表示創建一個排它鎖,在任意時間內,一個文件的排它鎖只能被一個進程擁有
- LOCK_UN:表示刪除該進程創建的鎖
- LOCK_MAND:它主要是用於共享模式強制鎖,它可以與LOCK_READ或者LOCK_WRITE聯合起來使用,從而表示是否允許並發的讀操作或者並發的寫操作。
我這次工作的應用場景是兩個py文件操作同一個文本,所以是多進程操作文本。
#!/usr/bin/python # coding:utf-8 import fcntl import threading import time def writetoTxt(): id = threading.currentThread().getName() with open("aaa.txt", "a") as f: # fcntl.flock(f.fileno(), fcntl.LOCK_EX) # 加鎖 print("{} acquire lock".format(id)) for i in range(10): f.write('"write from" + str(i) + {} \n'.format(id)) time.sleep(2) # 在with塊外,文件關閉,自動解鎖 print("{} exit".format(id)) if __name__ == '__main__': writetoTxt()
執行結果:
使用文件鎖
沒有使用文件鎖
如果從執行結果出發,我們看不出兩者之間的區別,我想應該是寫入內容太少了,看不出效果,有時間再研究下。
通過執行界面,我們是可以看出兩者的區別的:
使用文件鎖
從下面兩個圖中,我們可以看出,file_lock1.py文件是處於阻塞狀態的,但是沒有退出。
不使用文件鎖
說明這兩個進程都不會被阻塞。
注意:
1、文件close之火,文件鎖也會失效
2、進程結束后,文件鎖也會失效
3、flock()的LOCK_EX是"勸告鎖",系統內核不會強制檢查鎖的狀態,需要在代碼中進行文件操作的地方顯示檢查才能生效。
相關資料:
1.Linux中的文件鎖的概念及其實現(http://blog.csdn.net/jianhong1990/article/details/26369465)
2.fcntl模塊的官方文檔(https://docs.python.org/2/library/fcntl.html#fcntl.flock)
建議:
沒事還是多看看官方文檔吧,能收獲很多。