确保我的程序没有执行并发文件写入

发布于 2021-01-29 17:31:58

我正在编写对任何给定文件执行安全写操作所需的脚本,即如果不知道其他进程正在写入文件,则追加文件。我对该理论的理解是,使用文件系统上的写锁可以防止并发写操作,但实际情况并非如此。

这是我设置测试用例的方式:我正在重定向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代码的写入。

如何强制我的一个或两个并发进程不互相干扰?
我已阅读过一些人的建议,建议能够获取写文件句柄作为将文件写入安全的证据
这是我的操作系统和Python特有的行为吗?我在Ubuntu 12.04环境中使用Python2.7。

关注者
0
被浏览
48
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    从为并发检查描述的解决方案的启发中,我想到了以下代码片段。如果人们能够适当地预测所讨论文件的写入频率,它就可以工作。解决方案是通过使用文件修改时间。

    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
    

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



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看