防止在python中创建文件

时间:2011-04-05 23:13:43

标签: python sqlite

我正在研究一个python服务器,它同时处理许多数据库上的事务,每个数据库存储有关不同应用程序的性能数据。并发是通过多处理模块完成的,因此每个事务线程都在一个新进程中启动,并且共享内存数据保护方案不可行。   我使用sqlite作为我的DBMS,并选择在自己的文件中设置每个应用程序的DB。不幸的是,这引入了数据库创建的竞争条件;如果两个进程尝试同时为同一个新应用程序创建数据库,则两个进程都将创建要存储数据库的文件。我的研究让我相信一个文件在创建之前无法锁定;是否有其他机制可用于确保文件未创建然后同时写入?

提前致谢, 大卫

5 个答案:

答案 0 :(得分:1)

对于常规文件,通常的Unix式处理方法是尝试创建文件并查看它是否失败。在Python的情况下,那将是:

try:
    os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
except IOError: # or OSError?
    # Someone else created it already.

至少,您可以使用此方法尝试创建一个与数据库名称相似的“锁定文件”。如果创建了锁文件,则继续创建数据库。如果没有,您可以为“数据库存在”案例做任何您需要的事情。

答案 1 :(得分:0)

以确保不会发生冲突的方式命名数据库文件。

http://docs.python.org/library/tempfile.html

答案 2 :(得分:0)

您可以在尝试在代码和异常处理程序中创建文件时捕获错误,检查文件是否存在并使用现有文件而不是创建它。

答案 3 :(得分:0)

你没有提到这个平台,但是在linux open()或python中的os.open()中,需要一个可以使用的flags参数。如果文件不存在,O_CREAT标志会创建一个文件,如果文件已经存在,O_EXCL标志会给出错误。您还需要O_RDONLYO_WRONLYO_RDWR来指定访问模式。您可以在os模块中找到这些常量。

例如:fd = os.open(filename, os.O_RDWR | os.O_CREAT | os.O_EXCL)

答案 4 :(得分:0)

您可以使用POSIX O_EXCL and O_CREAT flags to open(2)来保证只有一个进程获取文件,从而保证数据库; O_EXCL将无法在NFSv2或更早版本上运行,并且将其依赖于其他网络文件系统会非常不稳定。

liblockfile库实现了open(2)联机帮助页中描述的网络文件系统安全锁定机制,这很方便;但我只看到预先制作的Ruby和Perl绑定。根据您的需要,提供Python绑定可能很有用,或者只是重新实现算法:

   O_EXCL Ensure that this call creates the file: if this flag is
          specified in conjunction with O_CREAT, and pathname
          already exists, then open() will fail.  The behavior of
          O_EXCL is undefined if O_CREAT is not specified.

          When these two flags are specified, symbolic links are not
          followed: if pathname is a symbolic link, then open()
          fails regardless of where the symbolic link points to.

          O_EXCL is only supported on NFS when using NFSv3 or later
          on kernel 2.6 or later.  In environments where NFS O_EXCL
          support is not provided, programs that rely on it for
          performing locking tasks will contain a race condition.
          Portable programs that want to perform atomic file locking
          using a lockfile, and need to avoid reliance on NFS
          support for O_EXCL, can create a unique file on the same
          file system (e.g., incorporating hostname and PID), and
          use link(2) to make a link to the lockfile.  If link(2)
          returns 0, the lock is successful.  Otherwise, use stat(2)
          on the unique file to check if its link count has
          increased to 2, in which case the lock is also successful.