Python多个用户同时追加到同一个文件

42

我正在编写一个python脚本,将通过网络访问,因此可能会有多个用户同时尝试向同一个文件追加内容。我的担忧是这可能会导致竞争条件,如果多个用户同时写入同一个文件,可能会破坏该文件。

例如:

#!/usr/bin/env python

g = open("/somepath/somefile.txt", "a")
new_entry = "foobar"
g.write(new_entry)
g.close

由于此操作看起来可能存在风险,我是否需要使用锁文件?


1
也许你可以只使用syslog? - Keith
如果你使用Linux或其他Unix系统,mkfifo 可能是一个不错的选择。 mkfifo 创建一个FIFO特殊文件。 任何人都可以随机地向该文件写入数据,然后只有一个进程从FIFO中读取数据。这样就不需要使用文件锁定了。 - Kenji Noguchi
如果您使用 O_APPEND 打开文件,目标文件系统符合 POSIX 标准,并且您的写操作足够短,可以在单个系统调用中完成,则不会发生任何损坏。 - Charles Duffy
4个回答

55
你可以使用文件锁定:

你可以使用文件锁定

import fcntl
new_entry = "foobar"
with open("/somepath/somefile.txt", "a") as g:
    fcntl.flock(g, fcntl.LOCK_EX)
    g.write(new_entry)
    fcntl.flock(g, fcntl.LOCK_UN)

请注意,如果您只写入小缓冲区,则在某些系统上,若进行追加操作,则不需要锁定,因为这些系统上的追加操作是原子性的


3
如果用户尝试向文件追加内容,但该文件被flock锁定,会发生什么?会出现错误吗? - Ray Y
3
不,该过程(更确切地说,是当前线程)只是在锁被释放前阻塞。有关更多信息,请参考man 2 flock - phihag
3
@Flint 不,blocked 的意思是 flock 在获取锁之前不会返回。 - phihag
2
这种情况可能会发生吗:进程A和B都以追加模式打开文件。 A获取锁定,写入,然后解锁。 B现在获取锁定并覆盖A写入的内容,因为当调用“open”时,文件的末尾是现在由A写入的行。我正在尝试使用175个进程写入文件,尽管它们在每个进程所属的单独日志文件中正确打印,但有些行被搞乱了,所以我想知道这是否可能是问题所在。B需要调用seek或其他方法移动到文件末尾吗?(我使用的是Debian 10,Python 3.7.5) - GoodDeeds
3
非常感谢您的帮助!由于我没有以二进制模式打开文件,因此无法使用“buffering = 0”,但在释放锁之前在文件描述符上使用“flush”解决了该问题。 - GoodDeeds
显示剩余8条评论

5
你没有说明使用的平台,但是这里有一个跨平台的模块可以使用: Python文件锁

这个链接已经失效了。 - Clay
14
不,它只是在休息。 - Qiau

5

1
根据您的平台/文件系统位置,这可能无法以安全的方式完成(例如NFS)。也许您可以写入不同的文件,然后合并结果?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接