桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载本篇文章以 C/zstdmt/README.md 为核心骨架系统讲解 7-Zip-zstd 项目中为 Brotli、Lizard、LZ4、LZ5 与 Zstandard 五种压缩算法提供的多线程MT封装库 zstdmt其基于 Zstandard Skippable Frame0x184D2A50的容器化帧格式、Brotli 特有的 16 字节扩展帧头、库的公开 API 与读/写回调约定以及仓库源码中的多线程工作模型与 7-Zip 集成方式。读完本文你将掌握该 MT 容器在字节层面上的精确布局、各算法的线程数与压缩级别取值范围并能基于 C/zstdmt 下的头文件独立接入这套多线程压缩/解压接口。一、zstdmt 是什么五种算法的统一多线程封装Brotli、Lizard、LZ4、LZ5 和 Zstandard 的参考实现本身大多是单线程的压缩速度受限于单核。zstdmt 是 Tino Reichardt 编写的一层薄封装它把每种算法的单次压缩单元frame按固定大小的输入块切分用多个 worker 线程并行压缩再把结果按 Zstandard 的 Skippable Frame 容器格式串联成一个合法、可被标准解码器识别为可跳过帧的流从而实现多线程压缩与多线程解压。从仓库布局看这五种算法的 MT 封装各有一套对称的文件族common 错误处理、compress、decompress与对应的公共头文件算法公共头文件压缩实现解压实现底层算法源码Brotlibrotli-mt.hbrotli-mt_compress.cbrotli-mt_decompress.cC/brotliLizardlizard-mt.hlizard-mt_compress.clizard-mt_decompress.cC/lizardLZ4lz4-mt.hlz4-mt_compress.clz4-mt_decompress.cC/lz4LZ5lz5-mt.hlz5-mt_compress.clz5-mt_decompress.cC/lz5Zstandard—使用官方 mt APIC/zstd/zstdmt_compress.c同左C/zstd其中 Zstandard 的多线程能力直接复用其官方ZSTDMT_*APIC/zstd/zstdmt_compress.c 与 C/zstd/zstdmt_compress.h而 zstd-mt_threading.c 为整个 zstdmt 库提供跨平台线程原语包装详见下文第五节。二、通用 Skippable Frame 容器Lizard / LZ4 / LZ5 / Zstandard 的 12 字节帧头README 明确给出了这套 MT 容器的核心设计所有压缩帧都包装成 Zstandard 的 Skippable Frame 格式魔法数固定为0x184D2A50每个压缩帧只需额外 12 字节的帧头开销。通用的 Skippable Frame 定义如下这是 C/zstdmt/README.md 的原表完整继承大小值说明4 字节0x184D2A50USkippable Frame 魔法数magic4 字节4Skippable Frame 自身大小即紧随其后只有 4 字节数据4 字节compressed size其后所跟压缩帧的大小压缩数据长度也就是说一个完整的 MT 压缩单元在字节流上是[4B magic][4B size4][4B compressed_size][compressed data ...]前 12 字节是容器帧头其后紧跟某一块输入数据的压缩结果。之所以选择 Skippable Frame 语义是因为标准的 Zstandard 解码器遇到该 magic 时会把它视为可跳过帧直接略过从而让这份 MT 流在非 MT 感知的工具里也能被容忍、被跳过不会因未知帧报错。这一 12 字节布局在源码中有直接印证LZ4、LZ5、Lizard、Brotli 四个 MT 头文件里都定义了同一个容器魔法数例如lz4-mt.h#define LZ4FMT_MAGICNUMBER 0x184D2204U与#define LZ4FMT_MAGIC_SKIPPABLE 0x184D2A50Ulz5-mt.h#define LZ5FMT_MAGIC_SKIPPABLE 0x184D2A50Ulizard-mt.h#define LIZARDFMT_MAGIC_SKIPPABLE 0x184D2A50Ubrotli-mt.h#define BROTLIMT_MAGICNUMBER 0x5242U /* BR */与#define BROTLIMT_MAGIC_SKIPPABLE 0x184D2A50U所有 MT 变体共用0x184D2A50U作为容器标识而各算法自己的帧类型魔法数如 LZ4 的0x184D2204U仍保留在压缩数据内部供其原生解码器识别。三、Brotli 的特有 16 字节帧头BR 魔法与解压分配提示Brotli 的封装与通用格式略有不同由于 Brotli 原生流没有自描述解压后大小的机制zstdmt 在帧头中额外携带了解压分配提示因此帧头从 12 字节扩展为 16 字节。README 中给出的 Brotli 帧定义如下原表完整继承大小值说明4 字节0x184D2A50USkippable Frame 魔法数与 zstd 一致4 字节8Skippable Frame 大小此处为 8 字节而非通用格式的 44 字节compressed size其后所跟压缩帧的大小压缩数据长度2 字节0x5242UBrotli 魔法数即 ASCII 字符BR2 字节uncompressed size解压器分配提示64KB × 此值可以这样理解 Brotli 帧的字节布局前 8 字节是 Skippable Frame 标准头magic size8后 8 字节是对该帧压缩数据的描述compressed size BR标志 分配提示。在 brotli-mt_compress.c 中可以看到这 16 字节帧头被逐字段写出的真实代码第 0 字节起写入BROTLIMT_MAGIC_SKIPPABLE第 4 字节起写入常量8第 8 字节起写入本次压缩后的实际大小wl-out.size第 12 字节起写入 2 字节的BROTLIMT_MAGICNUMBER0x5242最后第 14 字节起写入 2 字节的分配提示hintsize。其中hintsize的计算逻辑为若当前输入块实际小于预设inputsize则hintsize (in.size 16) 1否则hintsize inputsize 16——即向上取整到下一个 64KB 边界保证解压端分配的缓冲区足够容纳整个帧的解压结果。对应的校验与读取逻辑在 brotli-mt_decompress.c解压器依次校验size字段必须等于8、第 12 字节起的 2 字节必须等于BROTLIMT_MAGICNUMBER然后读取第 14 字节起的hintsize通过hintsize 16得到该帧解压缓冲区的建议大小并依据第 8 字节的compressed size动态扩容输入缓冲不足时realloc实现按帧头自描述、逐帧顺序解压的流程。四、库的使用方式上下文结构、回调式 I/O 与错误处理原 README 将库的用法指向独立的 testutils 与 lib 示例在本仓库中库的公开接口全部集中在 C/zstdmt 目录下的各*-mt.h头文件中。下面以 Brotli 为例其余算法接口完全同构说明接入这套库的完整调用范式接口细节来自 brotli-mt.h。4.1 压缩端 API/* 1) 创建压缩上下文 */ BROTLIMT_CCtx *BROTLIMT_createCCtx(int threads, uint64_t unpackSize, int level, int inputsize, int lgwin); /* 2) 执行多线程压缩错误通过返回值检查 */ size_t BROTLIMT_compressCCtx(BROTLIMT_CCtx *ctx, BROTLIMT_RdWr_t *rdwr); /* 3) 获取统计信息 */ size_t BROTLIMT_GetFramesCCtx(BROTLIMT_CCtx *ctx); /* 已生成的帧数 */ size_t BROTLIMT_GetInsizeCCtx(BROTLIMT_CCtx *ctx); /* 输入字节数 */ size_t BROTLIMT_GetOutsizeCCtx(BROTLIMT_CCtx *ctx); /* 输出字节数 */ /* 4) 释放上下文 */ void BROTLIMT_freeCCtx(BROTLIMT_CCtx *ctx);各参数的含义与取值范围均来自头文件注释与实现校验threads0 .. BROTLIMT_THREAD_MAX上限 128定义于 brotli-mt.h。传0表示不启用容器封装直接单线程处理原始 brotli 流输出裸 brotli 格式传1..128则启用 MT 容器。超过上限会在BROTLIMT_createCCtx内被拒绝并返回0见 brotli-mt_compress.c。levelBROTLIMT_LEVEL_MIN(0) .. BROTLIMT_LEVEL_MAX(11)对应 Brotli 压缩级别超出范围同样拒绝创建。inputsize每个 worker 每次读取的输入块大小传0时由库自动选择该级别下的较优值——具体实现为1024 * 1024 * (level ? level : 1)见 brotli-mt_compress.c即按级别线性放大分块以平衡压缩率与并行粒度传非 0 值则完全采用调用者的设置。unpackSize已知的输入总大小用于统计/进度未知可传0。lgwinBrotli 的滑动窗口大小参数2 的幂指数直接透传给BrotliEncoderCompress。其余算法的常量范围可在对应头文件中确认LZ4 为LZ4MT_THREAD_MAX128、LZ4MT_LEVEL_MIN1、LZ4MT_LEVEL_MAX12lz4-mt.hLZ5、Lizard 结构与之一致。4.2 解压端 APIBROTLIMT_DCtx *BROTLIMT_createDCtx(int threads, int threadsset, int inputsize); size_t BROTLIMT_decompressDCtx(BROTLIMT_DCtx *ctx, BROTLIMT_RdWr_t *rdwr); size_t BROTLIMT_GetFramesDCtx(BROTLIMT_DCtx *ctx); size_t BROTLIMT_GetInsizeDCtx(BROTLIMT_DCtx *ctx); size_t BROTLIMT_GetOutsizeDCtx(BROTLIMT_DCtx *ctx); void BROTLIMT_freeDCtx(BROTLIMT_DCtx *ctx);解压端threads同样支持00表示以单线程方式处理不带 skippable 帧的原始 brotli 流inputsize参数用于该模式的输入分块1..128则按 MT 容器解析。值得强调的是 brotli-mt_decompress.c 中实现的自动内容识别解压器会先把流的开头读入一块prebuf25616 字节的预读缓冲尝试区分裸 brotli 流与MT 容器流——若流以0x184D2A50size8BR魔法开头则走容器路径否则按原始 brotli 处理。这样一份由 MT 压缩产生的文件解压时即使调用方没有显式指定线程数也能被正确识别并按 MT 方式并行解压。4.3 回调式读写与 Buffer 结构库不绑定任何具体 I/O通过回调注入读写函数头文件注释明确说明可使用 stdio 函数或裸 read/write自行编写包装7-Zip ZS 中的封装即示例typedef struct { void *buf; /* 数据指针 */ size_t size; /* 当前已填充字节数 */ size_t allocated; /* buf 的分配长度 */ } BROTLIMT_Buffer; typedef int (fn_read) (void *args, BROTLIMT_Buffer *in); typedef int (fn_write) (void *args, BROTLIMT_Buffer *out); typedef struct { fn_read *fn_read; /* 读回调 */ void *arg_read; /* 读参数 */ fn_write *fn_write; /* 写回调 */ void *arg_write; /* 写参数 */ } BROTLIMT_RdWr_t;约定回调返回-1表示出错、返回0表示成功实际读/写的字节数写入in-size/out-size。4.4 错误处理所有 API 的size_t返回值遵循负数即错误的约定MT_ERROR(name)宏定义为((size_t)-BROTLIMT_error_##name)用BROTLIMT_isError(code)判断是否为错误码用BROTLIMT_getErrorString(code)取可读错误字符串。错误码枚举brotli-mt.h覆盖了内存分配失败、读/写失败、畸形输入、数据意外结束、单帧压缩/解压失败、压缩参数越界、底层压缩库错误、操作被取消等场景对应描述文本在 brotli-mt_common.c 中实现。五、多线程工作模型worker 循环与写队列zstdmt/README.md 只定义了容器格式而如何并行由源码实现决定。以 brotli-mt_compress.c 的头部注释为据其工作模型是无主线程的纯多 worker 版本每个线程自行循环执行四步——加读锁read_mutex读取一块输入释放读锁独立执行本块的压缩调用BrotliEncoderCompress输出缓冲按BrotliEncoderMaxCompressedSize(inputsize) 16预留帧头空间见 brotli-mt_compress.c加写锁write_mutex写入结果回到第 1 步直到输入耗尽。读锁保证多个 worker 不会读到同一段输入写锁保证输出顺序不乱。关键设计是三链表写队列brotli-mt_compress.c 与 list.h 中的 Linux 风格双向链表实现writelist_free空闲的输出缓冲可被复用writelist_busyworker 正在压缩中的缓冲writelist_done压缩完成、等待按序写出的缓冲。由于并行压缩的各帧完成顺序不定pt_write()brotli-mt_compress.c通过每个writelist上记录的frame序号与上下文中的curframe匹配保证输出流严格按帧序落盘只有当前应写出的帧就绪时才调用写回调否则等待写出一帧后curframe并继续检查后续帧是否也已就绪goto again循环从而在不阻塞并行压缩的前提下维护容器流的帧序不变。解压端brotli-mt_decompress.c采用同样的free/busy/done队列模型只是每帧的解压结果同样按帧号顺序写出。线程原语方面threading.h 在 POSIX 系统直接使用pthread.h在 Windows 上则通过 zstd-mt_threading.c 提供的 Pthread 包装实现兼容互斥量映射为CRITICAL_SECTION线程创建用_beginthreadex启动worker中转函数pthread_join用WaitForSingleObject(handle, INFINITE)等待完成。字节序相关的读写MEM_readLE32等与likely/unlikely等宏集中在 memmt.h 中保证帧头字段以 little-endian 稳定读写。六、在 7-Zip-zstd 中的集成与验证zstdmt 并不是孤立库它已被完整接入本仓库的 7-Zip 构建体系构建集成多个构建目标把 C/zstdmt 下的源文件编入。例如 CPP/7zip/Bundles/Alone/makefile.gcc 通过$(wildcard ../../../../C/zstdmt/lz4*.c)收集 LZ4/LZ5 MT 源码并追加zstd-mt_threading.cCPP/7zip/7zip.mak 也声明了$(ZSTDMT_OBJS)的目标规则。解压端自动识别CPP/7zip/Archive/BrotliHandler.cpp 的注释明确说明只有当用户显式用-mmt指定线程数时才向解码器强制传线程数否则BROTLIMT_decompressDCtx()会自行检查流的 skippable-frame 容器魔法自动决定按裸流单线程解压还是按容器多线程解压有容器时自动提升到最大处理器数。因此用-mmt压缩出的文件在未加-mmt的解压调用中也能被正确读取。回归测试仓库的 tests/regr-arc 目录下保留了test.txt.br-mt.br等多线程格式的测试样本配合 tests/main.test 与 tests/7z-test.tcl 可对 MT 容器的压缩/解压与回退行为做端到端验证。七、注意事项与兼容性边界基于上述源码事实使用 zstdmt 时有几点值得注意线程上限Brotli/LZ4/LZ5/Lizard 的 MT 库统一以128为线程数上限超限请求会在创建上下文阶段被拒绝返回空指针。threads0的特殊语义对 Brotli 等库而言0不是自动选择而是关闭容器、输出裸单线程流。若想输出标准 MT 容器必须传1..128。帧头开销通用容器每帧 12 字节、Brotli 每帧 16 字节分块越小并行度越高但开销占比越大inputsize默认按压缩级别自动放大1MB × level可视为库在并行度与压缩率之间的默认平衡点调用者可自行覆盖。解码兼容性MT 容器复用了 Zstandard 的 Skippable Frame 魔法标准 zstd 解码器会跳过这些帧而各算法的原生解码器只能解裸流要完整还原 MT 容器流必须使用本库的解压接口或支持该容器的 7-Zip-zstd 构建。许可zstdmt 库本身以 BSD 协议发布见 C/zstdmt/LICENSE7-Zip-zstd 整合后的整体许可见仓库根目录 COPYING。结语从字节布局到线程调度zstdmt 用一个 12/16 字节的 Skippable Frame 容器统一了五种压缩算法的多线程封装12 字节通用头承载0x184D2A50魔法与压缩尺寸Brotli 在此基础上追加BR魔法与 64KB 粒度的解压分配提示每个 worker 通过读锁取块 → 独立压缩 → 写锁按帧号顺序落盘的循环配合free/busy/done三链表队列维持输出帧序。理解这一容器格式既有助于在 7-Zip-zstd 之外复用 C/zstdmt 的 API 构建自己的多线程压缩工具也能让你在排查 MT 流问题时直接按本文的字节表手工解析或构造帧头。赞分享桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载相关推荐终极压缩神器7-Zip-zstd支持Zstd/Brotli的超级压缩工具全解析 终极压缩神器7 Zip zstd支持Zstd/Brotli的超级压缩工具全解析 7 Zip zstd是一款基于经典7 Zip开发的增强版开源压缩工具桌面应用CLITBOOX/TBOX Zip压缩ZIP归档格式的多文件压缩TBOOX/TBOX Zip压缩ZIP归档格式的多文件压缩 概述 在现代软件开发中数据压缩是提升存储效率和网络传输性能的关键技术。TBOX作为一个跨平台的C后端LazyCraft工作流引擎详解可视化编程如何提升AI开发效率LazyCraft工作流引擎详解可视化编程如何提升AI开发效率 LazyCraft是一款功能强大的AI开发工具其核心工作流引擎通过可视化编程方式让开发者无桌面应用CLI上一篇Ollama日志轮转配置磁盘空间优化与日志管理终极指南下一篇OHHTTPStubs Mocktail格式终极指南简化iOS网络测试数据管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考