curl 库并发传输监控:CURLMINFO_XFERS_RUNNING 详解与 multi 接口实战 curl 库并发传输监控CURLMINFO_XFERS_RUNNING 详解与 multi 接口实战【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLMINFO_XFERS_RUNNING是 libcurl 多句柄multi handle接口中用于查询当前正在运行中的 easy handle 数量的指标项它在多并发传输场景下是衡量活跃传输数的关键依据。本文以 CURLMINFO_XFERS_RUNNING.md 为核心结合 libcurl 源码实现讲解该指标的语义、API 用法、底层计数原理以及如何用它构建可观测的并发下载/上传程序。一、CURLMINFO_XFERS_RUNNING 是什么CURLMINFO_XFERS_RUNNING是CURLMinfo_offt枚举中的一个取值语义为当前正在运行的 easy handle 数量——即传输已经开始但尚未结束的句柄个数。该选项在 libcurl 8.16.0 版本中随curl_multi_get_offt()接口一同引入。在 include/curl/multi.h 中整个CURLMinfo_offt枚举定义了五个传输计数指标构成了一套完整的并发状态画像枚举值数值含义CURLMINFO_XFERS_CURRENT1当前已添加add 但未 remove的 easy handle 数CURLMINFO_XFERS_RUNNING2当前正在运行未完成且未排队的 easy handle 数CURLMINFO_XFERS_PENDING3正在等待启动受并行度、连接数限制等影响的 easy handle 数CURLMINFO_XFERS_DONE4已完成、等待应用通过curl_multi_info_read()读取结果的 easy handle 数CURLMINFO_XFERS_ADDED5历史上累计添加过的 easy handle 总数其中CURLMINFO_XFERS_RUNNING直接对应multi句柄内部的process集合见 lib/multihandle.h 中注释为 transfer being processed 的位集合。一个传输被调度器真正开始处理后才会被计入该集合因此它反映的是实际在跑的传输数而非被注册的传输数。二、API 签名与基本用法该指标通过curl_multi_get_offt()获取函数签名见 docs/libcurl/curl_multi_get_offt.md#include curl/curl.h CURLMcode curl_multi_get_offt(CURLM *handle, CURLMINFO_XFERS_RUNNING, curl_off_t *pvalue);handlecurl_multi_init()创建的 multi 句柄info要查询的指标项此处传CURLMINFO_XFERS_RUNNINGpvaluecurl_off_t类型的输出参数用于接收运行中的传输数量。文档给出的最小示例见 CURLMINFO_XFERS_RUNNING.mdint main(void) { CURLM *m curl_multi_init(); curl_off_t value; curl_multi_get_offt(m, CURLMINFO_XFERS_RUNNING, value); }curl_off_t是有符号的 64 位整数类型足以容纳任意规模的并发句柄计数。注意返回值不是查询结果本身而是状态码——查询到的数值写入pvalue指向的变量。三、返回码语义函数返回CURLMcode类型CURLM_OK0查询成功非零发生错误。若传入的info不是受支持的指标例如超出CURLMINFO_XFERS_*范围返回CURLM_UNKNOWN_OPTION若pvalue传入NULL返回CURLM_BAD_FUNCTION_ARGUMENT。错误码的完整定义可参考 libcurl-errors 文档libcurl-errors(3)。四、底层实现计数器从哪来要真正理解CURLMINFO_XFERS_RUNNING的语义需要看它的实现。在 lib/multi.c 的curl_multi_get_offt()中各指标的计算逻辑如下case CURLMINFO_XFERS_RUNNING: n Curl_uint32_bset_count(multi-process); if(n Curl_uint32_bset_contains(multi-process, multi-admin-mid)) --n; *pvalue (curl_off_t)n; break;从中可以提炼出三个实现事实计数来源CURLMINFO_XFERS_RUNNING统计的是multi-process位集合uint32_bset中的元素数量该集合在 lib/multihandle.h 中定义为 transfer being processed即正在被 multi 调度器处理的传输内部句柄剔除libcurl 会为内部任务如 DoH 解析创建管理员句柄multi-admin如果该句柄恰好在process集合中计数时会被减去保证返回的是应用可见的真实用户传输数。这与CURLMINFO_XFERS_CURRENT在 lib/multi.c 中包含内部句柄的语义形成对比与状态集合的关系process、pending等待中、msgsent已完成未取结果是三个相互区分的状态集合见 lib/multihandle.h因此运行数、等待数、完成数之和近似等于当前管理中的传输数可用于交叉校验。值得注意的细节是multi-admin在 lib/multi.c 的取址使用前依赖其非空从代码路径看multi_get_offt通过CURL_MAPI_ENTER的守卫机制进入临界区lib/multi.c保证了在多线程环境下读取计数的一致性。五、完整实战用 RUNNING 指标做并发进度监控将CURLMINFO_XFERS_RUNNING与curl_multi_perform()循环结合即可实现一个可观测的并发下载器核心骨架#include curl/curl.h #include stdio.h int main(void) { CURLM *m curl_multi_init(); CURL *easy[4]; curl_off_t running 0, current 0, pending 0; int still_running 0; int i; /* 添加 4 个并发传输 */ for(i 0; i 4; i) { easy[i] curl_easy_init(); curl_easy_setopt(easy[i], CURLOPT_URL, https://example.com/file); curl_easy_setopt(easy[i], CURLOPT_FRESH_CONNECT, 1L); /* 各自独立连接 */ curl_multi_add_handle(m, easy[i]); } do { CURLMcode rc curl_multi_perform(m, still_running); if(rc ! CURLM_OK) break; /* 关键指标采样 */ curl_multi_get_offt(m, CURLMINFO_XFERS_CURRENT, current); curl_multi_get_offt(m, CURLMINFO_XFERS_RUNNING, running); curl_multi_get_offt(m, CURLMINFO_XFERS_PENDING, pending); printf(current%lld running%lld pending%lld still_running%d\n, (long long)current, (long long)running, (long long)pending, still_running); if(still_running) curl_multi_poll(m, NULL, 0, 1000, NULL); /* 等待事件或超时 */ } while(still_running); curl_multi_cleanup(m); return 0; }运行要点在curl_multi_perform()循环内采样running值会随各传输的开始与结束在[0, 当前并发上限]之间变化当多个传输因CURLMOPT_MAX_TOTAL_CONNECTIONS等连接数限制排队时pending会上升而running保持受限两个指标配合可诊断传输是否真正在跑该 API 只是读取快照不会阻塞、不会驱动事件循环因此可在任何时刻安全调用。与 curl 命令行工具的对应关系curl命令行工具自身就是该指标的真实使用者。在 src/tool_progress.c 中工具会调用curl_multi_get_offt()读取CURLMINFO_XFERS_RUNNING与CURLMINFO_XFERS_ADDED并把它们渲染到进度条的两列中——Xfers列显示累计添加数Live列显示的正是当前正在运行的传输数。使用curl --parallel发起多 URL 下载时观察Live列即可实时看到活跃传输数量这正是CURLMINFO_XFERS_RUNNING在真实产品中的典型用法。六、版本与可用性引入版本8.16.0见 docs/libcurl/symbols-in-versions 中CURLMINFO_XFERS_RUNNING 8.16.0的记录当前仓库版本本仓库对应 libcurl 8.22.1-DEV见 include/curl/curlver.h已稳定支持该选项适用协议全部协议All与传输协议无关只反映 multi 调度层的并发状态默认值无n/a该选项是查询型指标不存在默认配置。编译时建议用CURL_VERSION_BITS宏做版本门控见 include/curl/curlver.h确保在低于 8.16.0 的旧版 libcurl 上安全降级#if LIBCURL_VERSION_NUM 0x081000 /* 8.16.0 */ curl_multi_get_offt(m, CURLMINFO_XFERS_RUNNING, running); #else running -1; /* 旧版本不支持 */ #endif七、与其他 XFERS 指标的搭配使用CURLMINFO_XFERS_RUNNING单独使用时只能回答有几个在跑若要完整掌握并发生命周期建议与整套枚举搭配各选项的独立手册见 CURLMINFO_XFERS_CURRENT、CURLMINFO_XFERS_PENDING、CURLMINFO_XFERS_DONECURRENT − (RUNNING PENDING DONE) ≈ 0校验调度状态一致性含内部句柄时需注意偏差PENDING 持续偏高并发上限或连接复用判定过严传输在排队RUNNING 持续偏低但 CURRENT 很大传输大多在等待未实际推进DONE 增长而应用未调用curl_multi_info_read()结果堆积需及时收割。小结CURLMINFO_XFERS_RUNNING是 libcurl multi 接口提供的活跃传输数快照语义清晰、开销极小与CURLMINFO_XFERS_CURRENT/PENDING/DONE/ADDED共同构成并发传输的完整观测面。理解其背后multi-process位集合的计数逻辑lib/multi.c有助于在多并发应用与工具开发中准确判断传输调度状态写出可观测、可诊断的高并发传输程序。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考