mar*_*r10 41 python locking file
解决这个问题最优雅的方法是什么:
内置函数的工作方式如下
>>> path = r"c:\scr.txt"
>>> file1 = open(path, "w")
>>> print file1
<open file 'c:\scr.txt', mode 'w' at 0x019F88D8>
>>> file2 = open(path, "w")
>>> print file2
<open file 'c:\scr.txt', mode 'w' at 0x02332188>
>>> file1.write("111")
>>> file2.write("222")
>>> file1.close()
Run Code Online (Sandbox Code Playgroud)
scr.txt现在包含'111'.
>>> file2.close()
Run Code Online (Sandbox Code Playgroud)
scr.txt被覆盖,现在包含'222'(在Windows上,Python 2.4).
解决方案应该在同一个进程中工作(如上例所示)以及另一个进程打开文件时.
如果崩溃程序不能保持锁定打开,则是首选.
Bri*_*ian 24
我不认为有完全跨平台的方式.在unix上,fcntl模块将为您执行此操作.但是在Windows上(我假设你是路径),你需要使用win32file模块.
幸运的是,有一个可移植的实现(portalocker)在python cookbook上使用平台适当的方法.
要使用它,请打开该文件,然后调用:
portalocker.lock(file, flags)
Run Code Online (Sandbox Code Playgroud)
其中flags是portalocker.LOCK_EX用于独占写访问,或LOCK_SH用于共享,读访问.
Fed*_*oni 11
解决方案应该在同一个进程中工作(如上例所示)以及另一个进程打开文件时.
如果通过"另一个进程",你的意思是"无论什么进程"(即不是你的程序),在Linux中,没有办法只在系统调用(fcntl和朋友)上实现这一点.你想要的是强制锁定,并且获取它的Linux方式更复杂:
使用mand选项重新安装包含文件的分区:
# mount -o remount,mand /dev/hdXYRun Code Online (Sandbox Code Playgroud)
为您的文件设置sgid标志:
# chmod g-x,g+s yourfileRun Code Online (Sandbox Code Playgroud)
在Python代码中,获取该文件的独占锁:
fcntl.flock(fd, fcntl.LOCK_EX)Run Code Online (Sandbox Code Playgroud)
现在,即使你释放锁定,cat也无法读取文件.
编辑:我自己解决了!通过使用目录存在和年龄作为锁定机制!按文件锁定仅在 Windows 上是安全的(因为 Linux 会静默覆盖),但按目录锁定在 Linux 和 Windows 上都可以完美运行。请参阅我的 GIT,我为此创建了一个易于使用的类“lockbydir.DLock”:
https://github.com/drandreaskrueger/lockbydir
在自述文件的底部,您会找到 3 个 GITplayer,您可以在其中看到代码示例在浏览器中实时执行!很酷,不是吗?:-)
感谢您的关注
我想回答 parity3 ( https://meta.stackoverflow.com/users/1454536/parity3 ) 但我既不能直接发表评论(“你必须有 50 个评论才能发表评论”),我也看不到任何联系方式他/她直接。你有什么建议给我,让他通过?
我的问题:
我已经实现了一些类似于 parity3 在这里建议的答案:https ://stackoverflow.com/a/21444311/3693375 (“假设你的 Python 解释器,以及......”)
它的工作非常出色 - 在 Windows 上。(我使用它来实现跨独立启动进程的锁定机制。https://github.com/drandreaskrueger/lockbyfile)
但除了 parity3 所说的,它在 Linux 上的工作方式不同:
os.rename(src, dst)
将文件或目录 src 重命名为 dst。... 在 Unix 上,如果 dst 存在并且是一个文件,如果用户有权限,它将被静默替换。如果 src 和 dst 在不同的文件系统上,则操作可能会在某些 Unix 风格上失败。如果成功,重命名将是一个原子操作(这是 POSIX 要求)。在 Windows 上,如果 dst 已经存在,将引发 OSError ( https://docs.python.org/2/library/os.html#os.rename )
无声替换是问题所在。在 Linux 上。“如果 dst 已经存在,将引发 OSError”对我来说非常有用。但遗憾的是,仅在 Windows 上。
我猜 parity3 的例子大部分时间仍然有效,因为他的 if 条件
if not os.path.exists(lock_filename):
try:
os.rename(tmp_filename,lock_filename)
Run Code Online (Sandbox Code Playgroud)
但是,整个事情不再是原子的。
因为 if 条件可能在两个并行进程中为真,然后两者都会重命名,但只有一个会赢得重命名竞赛。并没有引发异常(在 Linux 中)。
有什么建议?谢谢!
PS:我知道这不是正确的方法,但我缺乏替代方法。请不要用降低我的声誉来惩罚我。我环顾四周,自己解决了这个问题。如何在这里PM用户?而MEH我为什么不能?
我更喜欢使用filelock,这是一个跨平台的 Python 库,几乎不需要任何额外的代码。以下是如何使用它的示例:
from filelock import FileLock
lockfile = r"c:\scr.txt"
lock = FileLock(lockfile + ".lock")
with lock:
file = open(path, "w")
file.write("111")
file.close()
Run Code Online (Sandbox Code Playgroud)
块中的任何代码with lock:都是线程安全的,这意味着它将在另一个进程访问该文件之前完成。