python-文件鎖


  • 文件鎖(fcntl)
    • fcntl這個模塊是Python自帶的,但Windows沒有,可以手工下載fcntl.py文件,然后保存到python的Lib目錄下
    • 鎖類型(fcntl.flock函數的第二個參數)
    • LOCK_SH: 表示要創建一個共享鎖,所有進程沒有寫訪問權限,即使是加鎖進程也沒有。所有進程有讀訪問權限,在任意時間內,一個文件的共享鎖可以被多個進程擁有。
      LOCK_EX: 表示創建一個排他鎖,除加鎖進程外其他進程沒有對已加鎖文件讀寫訪問權限,在任意時間內,一個文件的排他鎖只能被一個進程擁有。
      LOCK_UN: 表示刪除該進程創建的鎖
      LOCK_NB: 如果指定此參數,函數不能獲得文件鎖就立即返回,否則,函數會等待獲得文件鎖。LOCK_NB可以同LOCK_SH或LOCK_NB進行按位或(|)運算操作。 fcnt.flock(f,fcntl.LOCK_EX|fcntl.LOCK_NB)
      LOCK_MAND:它主要是用於共享模式強制鎖,它可以與 LOCK_READ 或者 LOCK_WRITE 聯合起來使用,從而表示是否允許並發的讀操作或者並發的寫操作(盡管在 flock() 的手冊頁中沒有介紹LOCK_MAND,但是閱讀內核源代碼就會發現,這在內核中已經實現了)

# -*- coding:utf-8 -*-
'''
鎖類型(fcntl.flock函數的第二個參數)
LOCK_SH:  表示要創建一個共享鎖,在任意時間內,一個文件的共享鎖可以被多個進程擁有 
LOCK_EX:  表示創建一個排他鎖,在任意時間內,一個文件的排他鎖只能被一個進程擁有 
LOCK_UN:  表示刪除該進程創建的鎖 
LOCK_MAND:它主要是用於共享模式強制鎖,它可以與 LOCK_READ 或者 LOCK_WRITE 聯合起來使用,從而
           表示是否允許並發的讀操作或者並發的寫操作(盡管在 flock() 的手冊頁中沒有介紹 
           LOCK_MAND,但是閱讀內核源代碼就會發現,這在內核中已經實現了)
'''
import os
import sys
import time
import fcntl
import threading
import random

# 如下例子中,分別加鎖和不加鎖,結果
#   不加鎖時,多個線程間競爭文件寫權限,會出現覆蓋,導致寫內容不可預期(見test.log.withoutlock)
#   加鎖時,多個線程間會等待一個線程結束(因為設置的是阻塞鎖)后,第二個線程才開始寫,不會相互
#       覆蓋(見test.log.withlock)
def demo(name="null"):
    fp = open("test.log", "a+")
    cnt = 0
    # 在3s內隨機等待一段時間,打亂加鎖順序
    time.sleep(float(random.randint(0, 300)) / 300)
    fcntl.flock(fp, fcntl.LOCK_EX)
    print "call demo by %s" % name

    # 在10s內進行寫入,為了避免寫入的內容過多,寫0.5s,停0.5s
    for i in range(10):
        # 寫0.5s
        for i in range(100):
            fp.write("write by %s, %d\n" % (name, cnt))
            cnt += 1
            time.sleep(0.005)

        # 停0.5s
        time.sleep(0.5)
    fcntl.flock(fp, fcntl.LOCK_UN)
    fp.close()


if __name__ == "__main__":
    # 創建3個進程,並發寫入
    for cnt in range(3):
        name = "thread_%d" % cnt
        thd = threading.Thread(target=demo, args=(name,))
        thd.start()

未加鎖時,線程寫入異常
未加鎖時,線程寫入異常


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM