Python:锁定文件

Amb*_*sio 3 python locking

我有一个在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上的第二个进程块,而不是抛出异常.

Jon*_*son 6

您正在使用LOCK_NB标志,这意味着该呼叫是非阻塞的,并且只会在失败时立即返回.这可能发生在第二个过程中.它仍然能够读取文件的原因是portalocker最终使用flock(2)锁,并且,如flock(2)手册页中所述:

flock(2)只提供咨询锁; 给定对文件的适当权限,进程可以自由地忽略flock(2)的使用并对文件执行I/O.

要修复它,你可以直接使用fcntl.flock函数(在Linux上,portalocker只是一个薄的包装器)并检查返回的值以查看锁是否成功.


sky*_*ker 5

在摸索了许多方案之后,这对我来说是可行的。我有一个可以同时执行多次的脚本。我需要这些实例等待它们轮流读取/写入某些文件。无需删除锁定文件,因此,如果一个脚本失败,则可以避免在删除之前阻止所有访问。

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)