如何使用多个线程进行zlib压缩

时间:2015-05-18 03:42:03

标签: multithreading compression zlib

我有大量数据(大约2 GB),需要使用zlib(deflate())进行压缩。我目前正在读取500 kb的数据,压缩它并将其写入我的输出文件。

有1个帖子,一切都很好。数据被压缩,我可以写入并解压缩。

使用2个线程,进程将在deflate()调用中挂起。

以下是我的2个zlib comp线程调用的函数的大纲。

static z_stream z_str;

zlib_compress(...., bool last, bool first)
{

    if (first)
        deflateInit(&z_str, Z_DEFAULT_COMPRESSION);

    if (last)
        flush = Z_FINISH;
    else
        flush = Z_SYNC_FLUSH;

....
....
    status = deflate(&z_str, flush);
...
...
    if (last)
        deflateEnd(&z_str);

}

据我了解,这两个调用在调用deflate()时都指的是同一个zstream,这会导致不良行为。

我尝试将z_str作为局部变量并相应地修改代码。但是在解压缩时,假设512是文件的总大小,实际上只是第一块数据。

知道如何实现这个目标吗?

2 个答案:

答案 0 :(得分:3)

  

据我了解,这两个电话都指的是同一个zstream   同时调用deflate(),这会导致不良行为。

您期望发生什么?

每个线程都需要它自己的z_stream结构才能使用。同时访问同一z_stream的两个线程毫无意义。

答案 1 :(得分:1)

只要每个线程都有自己独立的z_stream对象,就可以让多个线程同时压缩数据。每个z_stream对象都应该调用deflateInit(),然后根据需要调用deflate(),然后在将所有未压缩数据传递给deflate()之后调用deflateEnd()。使用这种技术,例如,它是直截了当的。一次压缩两个不同的文件。

但是我怀疑你要做的是加快单个大文件的压缩,不是吗?在这种情况下,你会发现这是不可能的,至少不是以明显的方式。它不可能的原因是放气流的后一个字节依赖于该流的早期字节的含义 - 这意味着它们在生成所有早期字节之后才能生成,排除与前半部分并行生成压缩文件的后半部分。

您可以做的是生成两个单独的压缩文件;一个是未压缩文件的前半部分的压缩内容,另一个是未压缩文件的后半部分的压缩内容。这可以并行完成,因为两个压缩流将完全相互独立。请注意,您需要编写自己的例程来解压缩这两个文件并将结果再次连接回一个未压缩的文件,因为标准的压缩/解压缩实用程序不会意识到这种分而治之的技巧。

正如zlib(Adler)的原作者指出的那样,可以并行压缩大块数据,如pigz中所示。基本上,您需要提供32K未处理的数据,然后处理特定的块。

==Chunk 1===
       -32K-====Chunk 2=======
                       --32K--====Chunk 3====

然后您可以组合压缩数据。