我有一大块数据(大约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是文件的总大小,实际上只是第一块数据。
知道怎么做到这一点?
只要每个线程都有自己独立的z_stream对象,就可以让多个线程同时压缩数据。每个z_stream对象都应该调用deflateInit(),然后根据需要调用deflate(),然后在将所有未压缩数据传递给deflate()之后调用deflateEnd()。使用这种技术,例如,它是直截了当的。一次压缩两个不同的文件。
但是我怀疑你要做的是加快单个大文件的压缩,不是吗?在这种情况下,你会发现这是不可能的,至少不是以明显的方式。不可能的原因是放气流的后一个字节依赖于该流的早期字节的含义 - 这意味着它们在生成所有先前字节之后才能生成,这排除了生成压缩文件的后半部分与上半部分并行。
你可以做的是生成两个单独的压缩文件;一个是未压缩文件的前半部分的压缩内容,另一个是未压缩文件的后半部分的压缩内容。这可以并行完成,因为两个压缩流将完全相互独立。请注意,您需要编写自己的例程来解压缩这两个文件并将结果再次连接回一个未压缩的文件,因为标准的压缩/解压缩实用程序不会意识到这种分而治之的技巧。
正如zlib(Adler)的原作者指出的那样,可以并行压缩大块数据,如pigz中所示。基本上,您需要提供32K未处理的数据来处理特定的块。
==Chunk 1===
-32K-====Chunk 2=======
--32K--====Chunk 3====
然后,您可以组合压缩数据。
据我所知,两个调用都是在调用deflate()时引用相同的zstream,这会导致意外的行为。
你期望发生什么?
每个线程都需要它自己的z_stream
结构才能使用。两个线程同时访问相同的z_stream
是没有意义的。