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


当前回答

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

简单使用os.open(…, O_EXCL) + os.close()在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()

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

我更喜欢lockfile——平台独立的文件锁定

下面是一个如何使用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:块中的任何代码都是线程安全的,这意味着它将在另一个进程访问该文件之前完成。

场景是这样的: 用户请求一个文件执行某些操作。然后,如果用户再次发送相同的请求,它会通知用户在第一个请求完成之前不会完成第二个请求。这就是为什么我使用锁定机制来处理这个问题。

下面是我的工作代码:

from lockfile import LockFile
lock = LockFile(lock_file_path)
status = ""
if not lock.is_locked():
    lock.acquire()
    status = lock.path + ' is locked.'
    print status
else:
    status = lock.path + " is already locked."
    print status

return status

好吧,所以我最终用我在这里写的代码,在我的网站上链接是死的,在archive.org上查看(也可在GitHub上)。我可以以以下方式使用它:

from filelock import FileLock

with FileLock("myfile.txt"):
    # work with the file as it is now locked
    print("Lock acquired.")