我需要锁定一个文件写在Python。它将被多个Python进程同时访问。我在网上找到了一些解决方案,但大多数都无法达到我的目的,因为它们通常只是基于Unix或Windows的。


当前回答

在操作系统级别协调对单个文件的访问充满了您可能不想解决的各种问题。

最好的办法是有一个单独的进程来协调对该文件的读写访问。

其他回答

我曾经处理过这样的情况,我在同一个目录/文件夹中运行同一个程序的多个副本,并记录了错误。我的方法是在打开日志文件之前向磁盘写入一个“锁定文件”。程序在继续之前检查是否存在“锁文件”,如果“锁文件”存在,则等待轮到它。

代码如下:

def errlogger(error):

    while True:
        if not exists('errloglock'):
            lock = open('errloglock', 'w')
            if exists('errorlog'): log = open('errorlog', 'a')
            else: log = open('errorlog', 'w')
            log.write(str(datetime.utcnow())[0:-7] + ' ' + error + '\n')
            log.close()
            remove('errloglock')
            return
        else:
            check = stat('errloglock')
            if time() - check.st_ctime > 0.01: remove('errloglock')
            print('waiting my turn')

编辑—— 在考虑了上面关于过期锁的一些评论之后,我编辑了代码,添加了一个检查“锁文件”是否过期的检查。在我的系统上计算这个函数的几千次迭代,得到的平均值为0.002066…几秒钟前:

lock = open('errloglock', 'w')

到之后:

remove('errloglock')

所以我想我将从5倍的量开始,以表示过时并监控问题的情况。

此外,当我在处理计时时,我意识到我有一些并不真正必要的代码:

lock.close()

这是我在公开声明之后立即得到的,所以我在这次编辑中删除了它。

下面是一个如何使用filelock库的例子,它类似于Evan Fossmark的实现:

from filelock import FileLock

lockfile = r"c:\scr.txt"
lock = FileLock(lockfile + ".lock")
with lock:
    file = open(path, "w")
    file.write("123")
    file.close()

with lock:块中的任何代码都是线程安全的,这意味着它将在另一个进程访问该文件之前完成。

这里有一个跨平台的文件锁定模块:Portalocker

尽管正如Kevin所说,从多个进程同时写入文件是您希望尽可能避免的事情。

如果可以将问题硬塞到数据库中,则可以使用SQLite。它支持并发访问并处理自己的锁定。

我从grizzed -python中找到了一个简单而有效的(!)实现。

简单使用os.open(…, O_EXCL) + os.close()在windows上不起作用。

我一直在寻找几种解决方案,我的选择是 oslo.concurrency

它功能强大,文档也相对完善。它是基于紧固件的。

其他的解决方案:

Portalocker:需要pywin32,这是一个exe安装,所以不可能通过pip 紧固件:缺乏记录 lockfile:弃用 flufl。lock:用于POSIX系统的nfs安全文件锁定。 simpleflock:上次更新2013-07 佐。lockfile:上一次更新2016-06(截至2017-03) lock_file: 2007-10年最后一次更新