curl 8.20.0 如何搞定 DNS 解析多线程:资源池机制全解析
没人聊的 DNS 多线程坑
用 curl 同时查几十个 DNS,你知道后台在干嘛吗?一看你就傻眼了——要么惊呆,要么直皱眉。
以前,curl 的线程解析器是这样玩的:每个并行连接,就起一个新线程,还得开个 socketpair(Linux 上是 eventfd)来传结果。听着费劲吧?就是真费劲。
小打小闹的传输,没啥感觉。但企业级应用,一口气几千个连接?那就乱套了。每个线程吃内存、CPU,还占系统资源。socketpair 还多占文件描述符。几千个 easy handle 堆起来,资源直线爆表。
更烦的是,DNS 卡住不动,整个清理过程就堵死。想删 easy handle,结果线程卡着?应用直接死锁。
老办法(其实不咋地)
curl 团队有个补丁,叫 CURLOPT_QUICK_EXIT。一设置,线程就 detach,不用 join——适合要退出的应用。但你的程序得长期跑?detached 线程就堆内存里,像幽灵一样吃资源,直到进程挂。
纯属临时抱佛脚。
线程池上场:curl 8.20.0 大升级
新版 curl 直接扔掉老设计,在 multi handle 层加了线程池。
新玩法超优雅:
一个线程池,管海量连接
别每个 easy handle 一个线程了。现在一个 multi handle 配一个线程池。它:
- 需要时才起线程,不瞎预分配
- 闲着没事自动关线程
- 新 DNS 请求直接排队
- 结果用共享通知扔回来
- 解析完派给对应 easy handle
关键是:整个 multi handle 只一个 socketpair,不管多少并行连接。几百上千传输的文件描述符,瞬间省一大截。
你说了算
新选项 CURLMOPT_RESOLVE_THREADS_THREADS_MAX,让你限最大线程数。默认 20,团队会根据反馈调。
资源不再失控。想留 CPU 给业务,只用 5 个线程?设 5 就行。高吞吐要 50 个?随便你。
还有 multi 级的 CURLMOPT_QUICK_EXIT,管线程池怎么关。进程要退,就用它,不等清理。但现在 easy handle 没独占线程,删 handle 超安全。
晚到的 DNS 结果?easy handle 没了,直接丢。干净利落,没坑。
性能提升(基本都有)
省资源之外,性能还偷偷快了:好多 DNS 直接用现成线程跑。不用起线程、不重复 alloc、不多余系统调用。
大提速?看你应用和机器。但总比以前强——操作少,切换少,延迟稳。
现实提醒:新代码,新 Bug
说实话,这改动不小。代码多了,零件多了,边缘 case 藏得深。
开发者觉得没大祸,但大重构总有 Bug。赶紧在你环境测新版吧。
对你有啥好处
高吞吐应用,几千并行连接(爬虫、数据管道、分布式下载),8.20.0+ 超值。内存低、CPU 省、资源稳。
嵌入式或 IoT,内存 CPU 都金贵,线程和描述符减负,实打实帮上忙。
小规模用 curl,改进藏着,但 DNS 快点,系统调用少。基础设施暗爽,你看不见也赚了。
更大的意义
curl 的 DNS 2026 计划(线程池是核心),展现老司机工程:挖坑、给干净解法,还保兼容,加新选项。没砸锅,全升级。
开源维护者认真搞性能和资源,就是这味儿。
试过 curl 8.20.0 没?基础设施迁新版了?评论区聊聊你的经历——curl 团队超爱真人反馈,决策都听这个。