☰
curl 库并发传输监控:CURLMINFO_XFERS_RUNNING 详解与 multi 接口实战
2026/10/17 8:03:57 网站建设 项目流程

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);
  • handle:curl_multi_init()创建的 multi 句柄;
  • info:要查询的指标项,此处传CURLMINFO_XFERS_RUNNING;
  • pvalue:curl_off_t类型的输出参数,用于接收运行中的传输数量。

文档给出的最小示例(见 CURLMINFO_XFERS_RUNNING.md):

int 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_OK(0):查询成功;
  • 非零:发生错误。若传入的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;

从中可以提炼出三个实现事实:

  1. 计数来源:CURLMINFO_XFERS_RUNNING统计的是multi->process位集合(uint32_bset)中的元素数量,该集合在 lib/multihandle.h 中定义为 "transfer being processed",即正在被 multi 调度器处理的传输;
  2. 内部句柄剔除:libcurl 会为内部任务(如 DoH 解析)创建"管理员"句柄multi->admin,如果该句柄恰好在process集合中,计数时会被减去,保证返回的是应用可见的真实用户传输数。这与CURLMINFO_XFERS_CURRENT在 lib/multi.c 中"包含内部句柄"的语义形成对比;
  3. 与状态集合的关系: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_DONE):

  • CURRENT − (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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询