Python的zipfile是否线程安全?

11 投票
4 回答
6034 浏览
提问于 2025-04-17 12:35

在一个django项目中,我需要为数据库中的一些对象生成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环境下运行的

4 个回答

2

Python 3.5.5 版本让我们在使用 ZipFile 写入和读取多个 ZipExtFiles 时变得更安全,避免了线程之间的干扰。你可以在这里查看详细信息:https://docs.python.org/3.5/whatsnew/changelog.html#id93

据我所知,这个改动并没有被移植到 Python 2.7 版本。

更新:经过对代码的研究和一些测试后,发现这个锁定机制并没有完全实现。它只在 writestr 方法中正常工作,而在 openwrite 方法中则不行。

2

虽然这个问题已经有点时间了,但在谷歌搜索中还是排得很前,所以我想说一下我的观察。在Windows上使用64位的Python 3.4时,lzma的zipfile是线程安全的;而其他的就不行。

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

需要注意的是,你不能用多个zipfile.ZipFile实例去操作同一个文件,而是要在所有线程中使用同一个实例;在这里就是那个叫做zip的变量。

在我的情况下,我在8个核心和SSD的环境下,CPU使用率大约在80%到90%之间,这样的表现挺不错的。

6

不,这样说的话,它不是线程安全的。
如果你在同一个压缩文件里添加内容,就需要加锁,不然文件里的内容可能会搞乱。
但如果你是在不同的压缩文件里添加内容,使用不同的 ZipFile() 对象,那就没问题了。

撰写回答