我有一个在Linux上运行的Python应用程序.它每分钟都来自cron.它检查一个目录中的文件,如果找到一个它处理它 - 这可能需要几分钟.我不希望下一个cron作业拿起当前正在处理的文件,所以我使用下面调用portalocker的代码将其锁定.问题是它似乎不起作用.下一个cron作业设法为文件返回所有准备好处理的文件句柄.
def open_and_lock(full_filename):
file_handle = open(full_filename, 'r')
try:
portalocker.lock(file_handle, portalocker.LOCK_EX
| portalocker.LOCK_NB)
return file_handle
except IOError:
sys.exit(-1)
Run Code Online (Sandbox Code Playgroud)
任何想法我可以做什么来锁定文件所以没有其他进程可以得到它?
UPDATE
感谢@Winston Ewert我检查了代码,发现文件句柄在处理完成之前已经关闭了.它现在似乎正在工作,除了portalocker.lock上的第二个进程块,而不是抛出异常.
您正在使用LOCK_NB标志,这意味着该呼叫是非阻塞的,并且只会在失败时立即返回.这可能发生在第二个过程中.它仍然能够读取文件的原因是portalocker最终使用flock(2)锁,并且,如flock(2)手册页中所述:
flock(2)只提供咨询锁; 给定对文件的适当权限,进程可以自由地忽略flock(2)的使用并对文件执行I/O.
要修复它,你可以直接使用fcntl.flock函数(在Linux上,portalocker只是一个薄的包装器)并检查返回的值以查看锁是否成功.
在摸索了许多方案之后,这对我来说是可行的。我有一个可以同时执行多次的脚本。我需要这些实例等待它们轮流读取/写入某些文件。无需删除锁定文件,因此,如果一个脚本失败,则可以避免在删除之前阻止所有访问。
import fcntl
def acquireLock():
''' acquire exclusive lock file access '''
locked_file_descriptor = open('lockfile.LOCK', 'w+')
fcntl.lockf(locked_file_descriptor, fcntl.LOCK_EX)
return locked_file_descriptor
def releaseLock(locked_file_descriptor):
''' release exclusive lock file access '''
locked_file_descriptor.close()
lock_fd = acquireLock()
# ... do stuff with exclusive access to your file(s)
releaseLock(lock_fd)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10182 次 |
| 最近记录: |