Các giải pháp khác trích dẫn rất nhiều cơ sở mã bên ngoài. Nếu bạn muốn tự làm điều đó, đây là một số mã cho giải pháp đa nền tảng sử dụng các công cụ khóa tệp tương ứng trên các hệ thống Linux / DOS.
try:
# Posix based file locking (Linux, Ubuntu, MacOS, etc.)
import fcntl, os
def lock_file(f):
fcntl.lockf(f, fcntl.LOCK_EX)
def unlock_file(f):
fcntl.lockf(f, fcntl.LOCK_UN)
except ModuleNotFoundError:
# Windows file locking
import msvcrt, os
def file_size(f):
return os.path.getsize( os.path.realpath(f.name) )
def lock_file(f):
msvcrt.locking(f.fileno(), msvcrt.LK_RLCK, file_size(f))
def unlock_file(f):
msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, file_size(f))
# Class for ensuring that all file operations are atomic, treat
# initialization like a standard call to 'open' that happens to be atomic.
# This file opener *must* be used in a "with" block.
class AtomicOpen:
# Open the file with arguments provided by user. Then acquire
# a lock on that file object (WARNING: Advisory locking).
def __init__(self, path, *args, **kwargs):
# Open the file and acquire a lock on the file before operating
self.file = open(path,*args, **kwargs)
# Lock the opened file
lock_file(self.file)
# Return the opened file object (knowing a lock has been obtained).
def __enter__(self, *args, **kwargs): return self.file
# Unlock the file and close the file object.
def __exit__(self, exc_type=None, exc_value=None, traceback=None):
# Flush to make sure all buffered contents are written to file.
self.file.flush()
os.fsync(self.file.fileno())
# Release the lock on the file.
unlock_file(self.file)
self.file.close()
# Handle exceptions that may have come up during execution, by
# default any exceptions are raised to the user.
if (exc_type != None): return False
else: return True
Bây giờ, AtomicOpen
có thể được sử dụng trong một with
khối nơi người ta thường sử dụng một open
câu lệnh.
CẢNH BÁO: Nếu chạy trên Windows và Python gặp sự cố trước khi thoát được gọi, tôi không chắc hành vi khóa sẽ là gì.
CẢNH BÁO: Khóa được cung cấp ở đây là tư vấn, không tuyệt đối. Tất cả các quy trình có khả năng cạnh tranh phải sử dụng lớp "AtomicOpen".