【问题标题】:Is python zipfile thread-safe?python zipfile 是线程安全的吗?
【发布时间】:2012-02-08 14:26:19
【问题描述】:

在一个 django 项目中,我需要为 db 中的对象生成一些 pdf 文件。由于每个文件需要几秒钟的时间来生成,我使用 celery 来异步运行任务。

问题是,我需要将每个文件添加到 zip 存档中。我本来打算用python的zipfile模块,但是不同的任务可以在不同的线程中运行,我想知道如果两个任务同时尝试将一个文件添加到存档中会发生什么。

下面的代码线程安全吗?我在python的官方文档中找不到任何有价值的信息。

try:
    zippath = os.path.join(pdf_directory, 'archive.zip')
    zipfile = ZipFile(zippath, 'a')
    zipfile.write(pdf_fullname)
finally:
    zipfile.close()

注意:这是在 python 2.6 下运行的

【问题讨论】:

  • 你使用哪种 celery 并发方法?如果您的代码是在 celery 任务中使用默认的多处理并发方法执行的,那么它们将在单独的进程中执行,您无需担心线程安全。
  • 那么,问题不是线程安全,而是同时文件写入访问。

标签: python thread-safety zipfile


【解决方案1】:

不,从这个意义上说它不是线程安全的。 如果您要附加到同一个 zip 文件,则需要在那里锁定,否则文件内容可能会被打乱。 如果您要附加到不同的 zip 文件,使用单独的 ZipFile() 对象,那么您很好。

【讨论】:

    【解决方案2】:

    Python 3.5.5 使写入 ZipFile 和读取多个 ZipExtFiles 线程安全:https://docs.python.org/3.5/whatsnew/changelog.html#id93

    据我所知,该更改尚未向后移植到 Python 2.7。

    更新:在研究了代码和一些测试之后,很明显锁定仍然没有完全实现。它仅适用于writestr,不适用于openwrite

    【讨论】:

    • 在更新日志中查找bpo-14099
    • @AndreHolzner 是的,这就是我的意思。我对不完全支持的评论仍然是正确的,至少对于 3.5.5。
    【解决方案3】:

    虽然这个问题很老,但它仍然在谷歌搜索结果中居高不下,所以我只想插话说,我注意到在 windows 上的 python 3.4 64bit 上 lzma zipfile 是线程安全的;其他都失败了。

    with zipfile.ZipFile("test.zip", "w", zipfile.ZIP_LZMA) as zip:
        #do stuff in threads
    

    请注意,您不能将同一个文件与多个 zipfile.ZipFile 实例绑定,而是必须在所有线程中使用同一个;这里是名为 zip 的变量。

    在我的情况下,我在 8 个内核和 SSD 上获得了大约 80-90% 的 CPU 使用率,这很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      相关资源
      最近更新 更多