Eva*_*ark 133 python file-locking
我需要锁定一个文件以便用Python编写.它将同时从多个Python进程访问.我在网上找到了一些解决方案,但大多数都失败了,因为它们通常只基于Unix或基于Windows.
Eva*_*ark 99
好吧,所以我最终得到了我在这里写的代码,在我的网站链接已经死了,在archive.org上查看(也可以在GitHub上找到).我可以用以下方式使用它:
from filelock import FileLock
with FileLock("myfile.txt"):
# work with the file as it is now locked
print("Lock acquired.")
Run Code Online (Sandbox Code Playgroud)
Joh*_*uhy 38
这里有一个跨平台文件锁定模块:Portalocker
虽然凯文说,但是如果可能的话,你想要立即从多个进程写入文件.
如果您可以将问题塞进数据库,则可以使用SQLite.它支持并发访问并处理自己的锁定.
Tho*_*Lux 17
其他解决方案引用了许多外部代码库.如果您更愿意自己动手,这里有一些跨平台解决方案的代码,它使用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
Run Code Online (Sandbox Code Playgroud)
现在,AtomicOpen可以在with通常使用open语句的块中使用.
警告:如果在Windows上运行并且在调用exit之前Python崩溃,我不确定锁定行为是什么.
警告:此处提供的锁定是建议性的,而不是绝对的.所有潜在的竞争过程都必须使用"AtomicOpen"类.
Ric*_*eur 12
锁定是特定于平台和设备的,但通常,您有以下几种选择:
对于所有这些方法,您必须使用自旋锁(重试失败后)技术来获取和测试锁.这确实为错误同步留下了一个小窗口,但它通常小到不成为主要问题.
如果您正在寻找跨平台的解决方案,那么您最好通过其他机制登录到另一个系统(下一个最好的方法是上面的NFS技术).
请注意,sqlite受到与普通文件相同的NFS约束,因此您无法在网络共享上写入sqlite数据库并免费获得同步.
Max*_*ues 12
我一直在寻找几种解决方案,我的选择是 oslo.concurrency
它功能强大,记录相对较好.它基于紧固件.
其他方案:
Jos*_*eia 10
下面是如何使用filelock库的示例,它类似于Evan Fosmark 的实现:
from filelock import FileLock
lockfile = r"c:\scr.txt"
lock = FileLock(lockfile + ".lock")
with lock:
file = open(path, "w")
file.write("123")
file.close()
Run Code Online (Sandbox Code Playgroud)
块中的任何代码with lock:都是线程安全的,这意味着它将在另一个线程访问该文件之前完成。
协调对操作系统级别的单个文件的访问充满了您可能不想解决的各种问题.
您最好的选择是有一个单独的进程来协调对该文件的读/写访问.
锁定文件通常是特定于平台的操作,因此您可能需要允许在不同的操作系统上运行.例如:
import os
def my_lock(f):
if os.name == "posix":
# Unix or OS X specific locking here
elif os.name == "nt":
# Windows specific locking here
else:
print "Unknown operating system, lock unavailable"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141962 次 |
| 最近记录: |