當我們在讀寫文件的時候,如果該文件同時還被另一個進程操作,那么很容易出現(xiàn)混亂。這時候就需要加鎖了,正如操作數(shù)據(jù)庫表的時候需要加鎖一樣。 而 Python 提供了一個庫 fcntl,通過 fcntl.flock 函數(shù)即可實現(xiàn)對文件進行加鎖和解鎖。
fcntl.flock 接收兩個參數(shù),第一個參數(shù)是文件描述符,第二個參數(shù)是 operation。常見的 operation 如下: 1)fcntl.LOCK_SH:共享鎖,所有進程都可以對當前文件施加共享鎖; 2)fcntl.LOCK_EX:排他鎖,只能有一個進程對當前文件施加排他鎖,其他進程在施加的時候會阻塞; 3)fcntl.LOCK_UN:對加鎖文件進行解鎖; 4)fcntl.LOCK_MAND:共享模式強制鎖,可以和 LOCK_READ 或者 LOCK_WRITE 聯(lián)合起來使用,從而表示是否允許并發(fā)的讀操作或者并發(fā)的寫操作(基本不用); 5)fcntl.LOCK_NB:非阻塞鎖,如果指定此參數(shù),函數(shù)不能獲得文件鎖就立即返回;否則函數(shù)會等待獲得文件鎖,LOCK_NB 可以同 LOCK_SH、LOCK_EX 結(jié)合使用; 例如:如果一個文件設置了排他鎖:
那么當其它進程在請求獲取這個鎖的時候就會一直阻塞在這里。 但如果和 LOCK_NB 結(jié)合起來使用:
那么其它進程在獲取不到鎖的時候就直接返回了。
下面舉例說明,由于 fcntl 不支持 Windows,我們在 Linux 上測試。 開啟一個終端,打開 1.txt 并加上排他鎖,而一旦施加了排他鎖,其它進程就不能再加鎖了(包括共享鎖)。 這里再開啟一個終端,測試一下: 進程 1 已經(jīng)施加了排他鎖,進程 2 再加鎖的話就會阻塞,不管是共享鎖還是排他鎖都會阻塞。 然后我們再回到進程 1,將鎖釋放掉。 再來看看進程 2: 此時已經(jīng)不再阻塞了,因為第一個終端把鎖解除了。 我們說設置了排他鎖的話,其它進程在獲取不到鎖的時候會阻塞,但如果和 fcntl.LOCK_NB 結(jié)合使用的話,在獲取不到鎖的時候會直接返回。 進程 1 釋放鎖之后,已經(jīng)被進程 2 獲取,此時進程 2 給文件施加了排他鎖,然后我們繼續(xù)嘗試在進程 1 獲取。 因為此時獲取不到鎖,所以直接返回,告訴我們資源不可用。 |
|