如何使用多线程进行 zlib 压缩(相同输入源)

How to use multiple threads for zlib compression (same input source)

我的目标是在并行线程中压缩同源数据。 我定义了列表中的作业,这些作业具有读取信息(每个作业 500kb-1MB)。

我的压缩器线程将使用 ZLIB 压缩每个块的数据并将其存储在相应作业的 outbuf 中。

现在,我想合并所有这些并创建一个标准 ZLIB 格式的输出文件。

从 ZLIB RFC 和浏览 pigzee 的源代码后,我了解到

ZLIB header 如下所示

     +---+---+
     |CMF|FLG| (2 bytes)
     +---+---+
     +---+---+---+---+
     |     DICTID    | (4 bytes. Present only when FLG.FDICT is set)
     +---+---+---+---+
     +=====================+
     |...compressed data...| (variable size of data)
     +=====================+
     +---+---+---+---+
     |     ADLER32   |  (4 bytes of variable data)
     +---+---+---+---+

就我而言,也没有字典。

所以当我组合两个压缩单元时,所有单元的 header 是相同的。

因此,我正在做以下操作。

  1. 第一单元,我写的是header+压缩数据。

  2. 从第二个单元到最后一个单元,我只写压缩数据(没有header也没有预告片)

  3. 完成所有单元后,我正在使用 adlrer32_combine()并将所有作业输出数据的校验和转换为一个最终的 adler 32,然后用它更新输出文件在底部。

但问题是,我在 deflate 期间收到错误消息,说某些地方的数据无效。

有人试过这样的东西吗?任何相关信息都会很有帮助。

您不能简单地连接原始压缩数据流。每个 deflate 流都是自终止的,因此解压将在第一个流结束时结束。

您需要更仔细地查看 pigz 代码以了解如何合并 deflate 流。您可以使用 Z_SYNC_FLUSH 来完成最后一个块并将其带到字节边界而不结束放气流。然后你可以完成放气流,并剥离标记为结束块的最后一个空块。除了应该正常终止的最后一个放气流。然后你可以连接一系列 n-1 未终止的放气流和最后的 1 终止放气流。