如何在Python中安全地使用文件系统作为一种共享内存?

dsf9zpds  于 2023-01-04  发布在  Python
关注(0)|答案(1)|浏览(103)

TLDR:脚本A创建一个目录并在其中写入文件。脚本B定期检查该目录。脚本B如何知道脚本A何时完成写入以便访问文件?
我有一个Python脚本(称之为渲染服务器),它接收生成图像和相关数据的请求。我需要运行一个单独的Python应用程序(称之为消费者)来使用这些数据。消费者不知道新数据何时可用。理想情况下,它不需要知道脚本A的存在,只需要知道数据以某种方式变得可用。
我的快速而粗略的解决方案是有一个两个Python脚本都知道的outputs目录,在这个目录中,渲染服务器创建带有时间戳的目录,并在这些目录中保存几个文件。
渲染服务器执行如下操作:

os.makedirs('outputs/' + timestamped_subdir)
# Write files into that directory.

使用者检查该目录的方式类似于:

dirs = set()
while True:
    new_dirs = set(glob('outputs/*')).difference(dirs)
    if not len(new_dirs):
        continue
    # Do stuff with the contents of the latest new directory.

问题是使用者在渲染服务器完成写入之前检查目录的内容(这在FileNotFoundError中很明显)。我试图通过使渲染服务器执行以下操作来解决这个问题:

os.makedisr('temp')
# Write files into that directory.
shutil.copytree('temp', 'outputs/' + timestamped_subdir)

但是,在复制其中的文件之前,消费者仍然能够知道timestamped_subdir的存在(同样有一个FileNotFoundError)。什么是一种“正确”的方法来完成我试图实现的目标?
注:在写这篇文章的时候,我意识到我应该用shutil.move而不是shutil.copytree,这似乎已经解决了这个问题。但是我仍然不太确定这个操作的底层机制,以确定它是否正确工作。

vyswwuz2

vyswwuz21#

处理通过文件系统的通信的一种常见方式是依赖于文件或文件夹的原子重命名或链接。
更改“渲染服务器”以写入名为例如

outputs/' + timestamped_subdir + '_temp/'

当“渲染服务器”处理完该目录后,将其更改为执行

os.rename('outputs/' + timestamped_subdir + '_temp',  'outputs/' + timestamped_subdir)

只要所有内容都驻留在同一文件系统上,重命名就是原子的。
现在,其他进程只需忽略以_temp结尾的目录,当它看到另一个文件夹时,就会知道这些文件夹已经完成。

相关问题