1

我是 Python 初学者并面临以下问题:我有一个脚本定期读取设置文件并根据这些设置执行某些操作。我有另一个由某些 UI 触发的脚本,该脚本使用用户输入值写入设置文件。我使用 ConfigParser 模块来读取和写入文件。

我想知道这种情况是否能够导致不一致的状态(例如在读取设置文件的过程中,另一个脚本开始写入)。我不知道幕后是否有任何机制可以自动防止这种情况。

如果可能出现这种不一致,我可以使用什么来同步两个脚本并保持操作的完整性?

4

3 回答 3

1

我是 Python 初学者并面临以下问题:我有一个脚本定期读取设置文件并根据这些设置执行某些操作。我有另一个由某些 UI 触发的脚本,该脚本使用用户输入值写入设置文件。

当读取器读取而写入器写入文件时,可能存在竞争条件,因此读取器可能会在文件不完整时读取文件。

您可以通过在读取和写入时锁定文件来避免这种竞争(请参阅Linux flock()Python lockfile 模块),这样读者就不会观察到文件不完整。

或者,更好的是,您可以先写入一个临时文件,然后在完成后自动将其重命名为最终名称。这样读者和作者永远不会阻塞:

def write_config(config, filename):
    tmp_filename = filename + "~"
    with open(tmp_filename, 'wb') as file:
        config.write(file)
    os.rename(tmp_filename, filename)

当作者使用上述方法时,读者不需要进行任何更改。

于 2013-10-16T18:24:26.510 回答
0

当您编写配置文件时,首先将其写入临时文件。完成后,将其重命名为正确的名称。重命名操作 ( os.rename) 通常在 Unix 系统、Linux 和 Windows 上也是作为原子操作实现的,我认为,因此不会有其他进程在写入尚未完成时尝试读取配置的风险。

于 2013-10-16T18:22:51.137 回答
0

至少有两种方法可以解决此问题(假设您使用的是 unix-ish 系统):

  • 如果你想写,先写到一个临时文件,然后做一些unix可以原子地做的事情,尤其rename是临时文件到位。

  • 在任何操作期​​间锁定文件,例如在此文件锁定模块的帮助下。

就个人而言,我喜欢第一个选项,因为它利用了操作系统,尽管有些系统在原子性方面存在问题:关于如何在 Mac OS X 中破坏重命名- 另一个限制:重命名系统调用不能跨设备重命名文件。

于 2013-10-16T18:24:28.080 回答