
使用 curl_multi_get_offt 精确监控 libcurl 多句柄中的传输状态【免费下载链接】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导读curl_multi_get_offt是 libcurl 提供的一个多接口multi interface信息查询函数用于从CURLM多句柄中提取与传输数量相关的数值信息帮助开发者实时掌握多句柄当前管理了多少 easy handle、其中有多少正在运行、多少在排队等待、多少已完成但尚未取回结果。本文以 docs/libcurl/curl_multi_get_offt.md 为骨架结合 include/curl/multi.h 中的枚举定义与 lib/multi.c 中的底层实现完整介绍该函数的原型、五个信息选项的语义与源码级实现原理、返回值与错误处理并给出可直接编译运行的实战示例帮助读者在并发传输、连接复用等场景中精确监控传输进度。函数原型curl_multi_get_offt于 curl 8.16.0 版本加入见 docs/libcurl/symbols-in-versions 中记录的五个信息选项的引入版本声明位于头文件include/curl/multi.h中函数定义如下#include curl/curl.h CURLMcode curl_multi_get_offt(CURLM *multi_handle, CURLMinfo_offt info, curl_off_t *pvalue);三个参数的含义分别是参数含义multi_handle通过curl_multi_init()创建的多句柄即要查询的对象info要提取的信息类型类型为CURLMinfo_offt枚举当前可取五个CURLMINFO_XFERS_*选项pvalue输出参数指向curl_off_t类型变量的指针函数执行成功后该变量被写入查询结果CURLMinfo_offt是专门为这类返回 64 位数值的信息查询而设计的枚举类型其定义位于 include/curl/multi.h在CURLMINFO_NONE保留占位永远不要使用之后依次定义了五个取值typedef enum { CURLMINFO_NONE, /* first, never use this */ CURLMINFO_XFERS_CURRENT 1, /* 当前已添加但尚未移除的 easy handle 数 */ CURLMINFO_XFERS_RUNNING 2, /* 正在运行、既未完成也未排队的 easy handle 数 */ CURLMINFO_XFERS_PENDING 3, /* 等待启动的 easy handle 数 */ CURLMINFO_XFERS_DONE 4, /* 已完成、等待通过 curl_multi_info_read() 读取结果的 easy handle 数 */ CURLMINFO_XFERS_ADDED 5, /* 历史上总共添加过的 easy handle 数 */ CURLMINFO_LASTENTRY /* the last unused */ } CURLMinfo_offt;注意函数名中的offt即off_t表示返回值类型为curl_off_t一个有符号的 64 位整数类型。使用curl_off_t而不是普通的long可以保证在多句柄生命周期内累计的传输数量不会因整数宽度不足而溢出。五个信息选项详解CURLMINFO_XFERS_CURRENT当前管理的 easy handle 数量返回当前已添加到多句柄、但尚未移除的 easy handle 数量。不包含已经移除的句柄包含为内部任务添加的句柄例如通过 DoH 解析域名时产生的内部句柄。完整语义见 docs/libcurl/opts/CURLMINFO_XFERS_CURRENT.md。CURLMINFO_XFERS_RUNNING正在运行的 easy handle 数量返回当前正在运行的 easy handle 数量即传输已开始但尚未结束的句柄。当句柄已经完成、尚未处理或者正在排队等待时不计入该数值。完整语义见 docs/libcurl/opts/CURLMINFO_XFERS_RUNNING.md。CURLMINFO_XFERS_PENDING等待启动的 easy handle 数量返回当前等待启动的 easy handle 数量。一个已添加的传输可能因多种原因进入等待状态例如受连接数限制连接池容量、并发上限被迫等待空闲连接DNS 解析尚未完成无法确定已有的匹配连接是否允许多路复用HTTP/2 或 HTTP/3 的 multiplexing需要等待判断结果。完整语义见 docs/libcurl/opts/CURLMINFO_XFERS_PENDING.md。CURLMINFO_XFERS_DONE已完成但未取回结果的 easy handle 数量返回当前已完成、但尚未通过curl_multi_info_read()处理结果的 easy handle 数量。这部分句柄的结果仍滞留在多句柄内部的消息队列中等待应用层读取。完整语义见 docs/libcurl/opts/CURLMINFO_XFERS_DONE.md。CURLMINFO_XFERS_ADDED累计添加的 easy handle 总数返回多句柄历史上总共添加过的 easy handle 数量累计值只增不减同样包含 DoH 解析等内部任务产生的句柄。若想知道当前正在管理的数量应使用CURLMINFO_XFERS_CURRENT。完整语义见 docs/libcurl/opts/CURLMINFO_XFERS_ADDED.md。五个选项可概括为一张对照表信息选项枚举值含义典型用途CURLMINFO_XFERS_CURRENT1当前已添加未移除的句柄数判断多句柄当前负载CURLMINFO_XFERS_RUNNING2正在运行的句柄数判断活跃传输量CURLMINFO_XFERS_PENDING3等待启动的句柄数判断是否因连接限制而排队CURLMINFO_XFERS_DONE4已完成未读取结果的句柄数判断是否需要调用curl_multi_info_read()CURLMINFO_XFERS_ADDED5累计添加过的句柄总数统计历史吞吐量底层实现原理从源码看lib/multi.c 中curl_multi_get_offt的实现与文档描述完全一致每个选项对应多句柄内部的一个数据结构CURLMINFO_XFERS_CURRENT读取multi-xfersCurl_uint32_tbl类型的句柄表中的条目数由于多句柄内部会维护一个multi-admin管理句柄统计时如果该管理句柄在表中会先减去 1确保返回的是用户可见的传输数量CURLMINFO_XFERS_RUNNING统计multi-processCurl_uint32_bset类型的位集合中正在处理的条目同样会扣除admin管理句柄本身CURLMINFO_XFERS_PENDING直接统计multi-pending位集合中的条目数CURLMINFO_XFERS_DONE统计multi-msgsent位集合中的条目数即已完成并进入消息发送队列、等待curl_multi_info_read()取走的句柄CURLMINFO_XFERS_ADDED直接返回multi-xfers_total_ever计数器这是一个只增不减的累计值。函数内部通过CURL_MAPI_ENTER/CURL_MAPI_LEAVE守卫机制保证并发安全。如果传入的info不在上述五个枚举值中走default分支把*pvalue置为-1并返回CURLM_UNKNOWN_OPTION。实现中还体现了一个重要细节pvalue不允许为NULL如果传入空指针函数直接返回CURLM_BAD_FUNCTION_ARGUMENT参数错误。返回值与错误处理函数返回CURLMcode类型遵循0 表示成功、非 0 表示出错的约定CURLM_OK0查询成功*pvalue中写入了有效数值CURLM_BAD_FUNCTION_ARGUMENTpvalue为空指针由 lib/multi.c 中的参数校验产生CURLM_UNKNOWN_OPTIONinfo不是有效的CURLMINFO_XFERS_*选项此时*pvalue会被置为-1其他非零值表示发生了其他错误完整的错误码说明参见 docs/libcurl/libcurl-errors.md即手册中的libcurl-errors(3)。完整示例下面是一个完整的可编译示例演示了创建多句柄、添加 easy handle 后查询CURLMINFO_XFERS_ADDED的用法#include curl/curl.h int main(void) { /* init a multi stack */ CURLM *multi curl_multi_init(); CURL *curl curl_easy_init(); curl_off_t n; if(curl) { /* add the transfer */ curl_multi_add_handle(multi, curl); curl_multi_get_offt(multi, CURLMINFO_XFERS_ADDED, n); /* on successful add, n is 1 */ } }对应的五个选项各自的调用示例可以参考对应选项文档中的EXAMPLE小节CURLMINFO_XFERS_CURRENT见 docs/libcurl/opts/CURLMINFO_XFERS_CURRENT.md、CURLMINFO_XFERS_RUNNING见 docs/libcurl/opts/CURLMINFO_XFERS_RUNNING.md、CURLMINFO_XFERS_PENDING见 docs/libcurl/opts/CURLMINFO_XFERS_PENDING.md、CURLMINFO_XFERS_DONE见 docs/libcurl/opts/CURLMINFO_XFERS_DONE.md、CURLMINFO_XFERS_ADDED见 docs/libcurl/opts/CURLMINFO_XFERS_ADDED.md。在实际的多接口事件循环中一个典型的使用模式是在每轮curl_multi_perform()或等价的curl_multi_poll()之后查询CURLMINFO_XFERS_RUNNING判断是否还有活跃传输查询CURLMINFO_XFERS_PENDING判断是否有句柄因连接限制而排队查询CURLMINFO_XFERS_DONE判断是否有已完成结果等待通过curl_multi_info_read()取走后者的语义可参考 docs/libcurl/curl_multi_info_read.md查询CURLMINFO_XFERS_CURRENT与CURLMINFO_XFERS_ADDED则分别用于把握当前负载与历史吞吐量。使用注意事项该函数适用于所有协议文档中Protocol: All与具体传输协议无关可以在任何多接口应用中安全使用返回值统一为curl_off_t64 位有符号整数适合累计计数场景不会轻易溢出统计口径包含内部句柄如 DoH 解析句柄在高频添加/移除句柄时CURLMINFO_XFERS_CURRENT等瞬时值可能短暂包含内部任务精确语义请以 include/curl/multi.h 中枚举注释与 lib/multi.c 的实现为准该 API 自 curl 8.16.0 起可用使用前请确认链接的 libcurl 版本不低于此版本可参见 docs/libcurl/symbols-in-versions调用前务必为pvalue提供有效的非空指针并检查返回值避免将-1误当作有效计数。通过合理组合这五个信息选项开发者可以精确掌握多句柄内部每一个传输的生命周期阶段排队、运行、完成、累计为并发下载器、批量请求调度等场景提供可靠的监控与调度依据。【免费下载链接】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),仅供参考