我需要锁定一个文件以便用 Python 编写。它将同时从多个 Python 进程访问。我在网上找到了一些解决方案,但大多数都无法满足我的目的,因为它们通常仅基于 Unix 或基于 Windows。
原文由 Evan Fosmark 发布,翻译遵循 CC BY-SA 4.0 许可协议
我需要锁定一个文件以便用 Python 编写。它将同时从多个 Python 进程访问。我在网上找到了一些解决方案,但大多数都无法满足我的目的,因为它们通常仅基于 Unix 或基于 Windows。
原文由 Evan Fosmark 发布,翻译遵循 CC BY-SA 4.0 许可协议
其他解决方案引用了大量外部代码库。如果您更愿意自己做,这里有一些跨平台解决方案的代码,它在 Linux / DOS 系统上使用各自的文件锁定工具。
try:
# Posix based file locking (Linux, Ubuntu, MacOS, etc.)
# Only allows locking on writable files, might cause
# strange results for reading.
import fcntl, os
def lock_file(f):
if f.writable(): fcntl.lockf(f, fcntl.LOCK_EX)
def unlock_file(f):
if f.writable(): 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
现在, AtomicOpen
可以在 with
块中使用,其中通常使用 open
语句。
警告:
fcntl.lock
变得非法。原文由 Thomas Lux 发布,翻译遵循 CC BY-SA 4.0 许可协议
2 回答5.2k 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
4 回答1.4k 阅读✓ 已解决
3 回答1.3k 阅读✓ 已解决
3 回答1.3k 阅读✓ 已解决
2 回答895 阅读✓ 已解决
1 回答1.8k 阅读✓ 已解决
好吧,所以我最终使用了我在此处编写的代码,在我的网站上链接已失效,请在 archive.org 上查看( 也可在 GitHub 上找到)。我可以按以下方式使用它: