【问题标题】:Ensuring that my program is not doing a concurrent file write确保我的程序没有进行并发文件写入
【发布时间】:2014-01-14 23:18:26
【问题描述】:

我正在编写一个脚本,该脚本需要对任何给定文件执行安全写入,即,如果已知没有其他进程正在写入文件,则附加一个文件。我对该理论的理解是,在文件系统上使用写锁可以防止并发写入,但在实践中似乎并非如此。

以下是我设置测试用例的方式: 我正在重定向 ping 命令的输出:

ping 127.0.0.1 > fileForSafeWrites.txt

另一方面,我有以下 python 代码尝试写入文件:

handle = open('fileForSafeWrites.txt', 'w')
handle.write("Probing for opportunity to write")
handle.close()

同时运行两个进程优雅地完成。我看到 fileForSafeWrites.txt 已经变成了一个包含二进制内容的文件,而不是第一个进程发出的写锁,以防止它被 Python 代码写入。

我如何强制我的一个或两个并发进程不相互干扰?我读过人们建议能够获取写入文件句柄作为文件被写入安全的证据,比如在https://stackoverflow.com/a/3070749/1309045

此行为是否特定于我的操作系统和 Python。我在 Ubuntu 12.04 环境下使用 Python2.7。

【问题讨论】:

  • 您在哪里获取文件的锁定?在类似 UNIX 的操作系统中,两个文件同时写入一个文件是完全可以接受的,除非您明确阻止它,否则这正是将发生的情况。
  • 谢谢,我没有获得锁。我期待前一个进程对第二个进程发出写锁。我被 stackoverflow.com/a/3070749/1309045 误导了。如果你说的是真的,那么stackoverflow.com/questions/3070210/…的答案是什么

标签: python unix file-io operating-system ubuntu-12.04


【解决方案1】:

使用lockfile模块,如Locking a file in Python所示

【讨论】:

  • 如果我可以控制这两个进程,则可以使用。如果您假设其中一个进程是外部的,程序员无法控制并且不能被要求发出锁怎么办? (ping 是为了暗示这一点)
  • 正如您问题的 cmets 中所建议的,在类 UNIX 操作系统中同时写入文件是完全有效的。这就是您在 Python 中实现文件锁定(一种方式)的方式。如果您可以控制其他进程并希望写入 ACID 文件,则必须找出其他方法。例如:事务、数据库、酸性文件系统等
【解决方案2】:

solution described for concurrency checks 的启发,我想出了下面的sn-p 代码。如果能够适当地预测写入相关文件的频率,它就会起作用。解决方案是使用文件修改时间。

import os
import time

'''Find if a file was modified in the last x seconds given by writeFrequency.'''
def isFileBeingWrittenInto(filename, 
                       writeFrequency = 180, overheadTimePercentage = 20):

    overhead = 1+float(overheadTimePercentage)/100 # Add some buffer time
    maxWriteFrequency = writeFrequency * overhead
    modifiedTimeStart = os.stat(filename).st_mtime # Time file last modified
    time.sleep(writeFrequency)                     # wait writeFrequency # of secs
    modifiedTimeEnd = os.stat(filename).st_mtime   # File modification time again
    if 0 < (modifiedTimeEnd - modifiedTimeStart) <= maxWriteFrequency:
        return True
    else:
        return False

if not isFileBeingWrittenInto('fileForSafeWrites.txt'):
    handle = open('fileForSafeWrites.txt', 'a')
    handle.write("Text written safely when no one else is writing to the file")
    handle.close()

这不会进行真正的并发检查,但可以结合各种其他实用方法来安全地写入文件,而不必担心文本乱码。希望它可以帮助下一个寻找方法的人。

编辑更新

经过进一步测试,我遇到了一个高频写入过程,需要从

修改条件逻辑
if 0 < (modifiedTimeEnd - modifiedTimeStart) < maxWriteFrequency 

if 0 < (modifiedTimeEnd - modifiedTimeStart) <= maxWriteFrequency 

从理论上和实践上来说,这是一个更好的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    相关资源
    最近更新 更多