从多个脚本实例安全地写入同一文件?

时间:2014-06-20 05:31:31

标签: python

所以我有一个脚本,当在监视目录中检测到新的文件事件时会被触发。在脚本中我有这个功能,它将读取并保存东西到conf文件。目前,我尝试不允许运行多个脚本实例以避免竞争条件并最终破坏已保存的文件。

现在,当我有多个脚本实例尝试写入同一个文件时,我正在试图弄清楚如何使这个函数安全地写入conf文件。前几天我读到了fcntl模块的文件锁定,但是我的头脑很少,我不确定它是如何工作的

def save_task_details(resp, filepath):
    conf = ConfigParser.SafeConfigParser()
    conf.read(CFG_PATH)

    filehash = get_filehash(filepath)
    if not conf.has_section(filehash):
        conf.add_section(filehash)

    conf.set(filehash, "filename", os.path.basename(filepath))
    conf.set(filehash, "id", resp.id)

    # ...

    with open(CFG_PATH, "wb") as configfile:
        conf.write(configfile)

2 个答案:

答案 0 :(得分:0)

从多个进程写入单个文件总是很棘手,最好避免使用。

选项很少

文件锁定

没有标准库。过时锁定和文件无法访问的可能问题

写入基于文件的数据库

好的案例是sqlite,其他人也可能。如果另一个脚本正在处理共享数据,您可能会遇到暂时阻止脚本的情况,但这实际上是您想要的。

使用现有服务

与数据库一样,但Redisetcd等键值存储也可以作为解决方案。

运行您自己的服务

编写这样的服务并不是那么困难(我会继续使用zmq进行进程间通信,无论是在普通(没有其他包)还是作为zerorpc的一部分,这允许暴露服务非常容易。

答案 1 :(得分:0)

文件锁定似乎相当成问题,并且数据库不适合编写配置文件,因此,如果您对第三方模块没有不利并且您使用的是* nix,则可以考虑使用posix_ipc命名的信号量来协调写入配置文件。只需要很少的额外代码:

import posix_ipc as ipc

def save_task_details(resp, filepath):

    # ...

    with ipc.Semaphore('/config_semaphore', flags=ipc.O_CREAT, initial_value=1), open(CFG_PATH, "wb") as configfile:
           conf.write(configfile)