我是一名Python初学者并面临以下问题:我有一个脚本定期阅读设置文件并根据这些设置执行某些操作。我有一些由用户输入值写入设置文件的UI触发的脚本。我使用ConfigParser模块来读取和写入文件。
我想知道这种情况是否能够导致不一致的状态(比如在读取设置文件的中间,另一个脚本开始写入)。我不知道场景背后是否有任何机制可以自动防止这种情况发生。
如果可能出现这种不一致的情况,我可以使用什么来同步两个脚本并保持操作的完整性?
答案 0 :(得分:1)
我是一名Python初学者并面临以下问题:我有一个脚本定期阅读设置文件并根据这些设置执行某些操作。我有一些由用户输入值写入设置文件的UI触发的脚本。
当编写器写入文件时读取器读取时可能存在竞争条件,以便读取器可以在文件不完整时读取该文件。
您可以通过在读写时锁定文件来保护此种族(请参阅Linux flock()或Python lockfile module),以便读者永远不会观察到文件不完整。
或者,更好的是,您可以先写入一个临时文件,并在完成rename时以原子方式写入最终名称。这样,读者和作者永远不会阻止:
def write_config(config, filename):
tmp_filename = filename + "~"
with open(tmp_filename, 'wb') as file:
config.write(file)
os.rename(tmp_filename, filename)
当作者使用上述方法时,读者无需进行任何更改。
答案 1 :(得分:0)
编写配置文件时首先将其写入临时文件。完成后,将其重命名为正确的名称。重命名操作(os.rename
)通常在Unix系统,Linux和Windows上实现为原子操作,我认为,因此在写入时没有其他进程尝试读取配置的风险已经完成了。
答案 2 :(得分:0)
至少有两种方法可以解决这个问题(假设您使用的是unix-ish系统):
如果你想写,先写一个临时文件,然后做一些unix can do atomically,特别是rename
临时文件到位。
在任何操作期间锁定文件,例如借助此filelock模块。
就个人而言,我喜欢第一个选项,因为它使用操作系统,虽然有些系统存在原子性问题:On how rename is broken in Mac OS X - 另一个限制:重命名系统调用无法跨设备重命名文件。