网易首页 > 网易号 > 正文 申请入驻

两种系统哲学的分野:为什么 Windows 选择了 IOCP?

0
分享至


本文来自微信公众号: 宇众不同的露萱 ,作者:宇众不同的露萱,原文标题:《两种系统哲学的分野:为什么 Windows 选择了 IOCP?》

一个值得琢磨的对比:Linux世界里,从select、poll一路演化到epoll,再到近几年的io_uring,这条路走了将近三十年。而Windows,早在1994年发布Windows NT 3.5的时候,就已经提供了一套至今几乎没有被替代过的高并发I/O模型——IOCP(I/O Completion Port,I/O完成端口)。更耐人寻味的是,Linux最新的io_uring,设计哲学上居然和这套快三十年前的Windows方案越来越像。这中间到底发生了什么?

故事背景:1990年代初,一台服务器该怎么同时伺候成千上万个连接?

把时间拨回1980年代末到1990年代初。彼时,微软正在打造一个全新的操作系统内核,用来彻底取代老旧的DOS架构——这就是后来的Windows NT。负责这个项目的核心人物,是从DEC(数字设备公司)挖来的传奇工程师Dave Cutler,他此前主导设计了DEC的VMS操作系统,是操作系统内核设计领域举足轻重的人物。

Windows NT从一开始就瞄准的是服务器级别的场景——这意味着它必须直面一个当时几乎所有操作系统都在挣扎的问题:当一台服务器需要同时处理成百上千个网络连接时,操作系统的I/O模型该怎么设计,才能既保证并发能力,又不把CPU和内存资源全部耗死在"等待"上?

这个问题后来在互联网爆发的年代,被Unix社区称为著名的C10K问题——如何让一台服务器同时支撑一万个并发连接。而在Windows NT诞生的那个更早的年代,微软的内核团队已经在为类似的挑战寻找答案,只不过他们走的是一条和后来Unix世界主流路线截然不同的道路。

旧方案为什么失败?

每连接一个线程(Thread-Per-Connection):这是最直觉的方案——每来一个客户端连接,就创建一个线程专门处理它的读写。逻辑清晰、编程模型简单,几乎是当时大多数网络服务的标准写法。但问题在于,线程从来不是免费的资源:每个线程都需要独立的内核栈空间(通常是1MB量级),当连接数达到几千甚至上万时,仅仅是线程本身占用的内存就已经相当可观,更致命的是,操作系统在成百上千个线程之间来回**上下文切换(Context Switch)**的开销,会随着线程数量增长而急剧膨胀——大部分CPU时间被浪费在"决定接下来运行哪个线程"这件事本身,而不是真正处理业务逻辑。

阻塞式同步I/O:线程调用一次读操作,如果数据还没到达,线程就会被操作系统挂起,直到数据就绪。这种模型下,一个线程在等待I/O的这段时间里完全是"死"的,无法做任何其他有意义的工作——如果你想同时处理多个连接,唯一的办法就是开更多线程,回到上面那个死胡同。

基于消息循环的异步通知(比如早期Windows提供的WSAAsyncSelect):把I/O事件转换成Windows消息,投递到应用程序的消息队列里,程序在消息循环里处理这些通知。这种方式确实避免了阻塞,但它天然和Windows的GUI消息机制绑定在一起,在真正高并发、高吞吐的服务器场景下,消息队列的处理效率和扩展性都远远不够。

这些方案共同的困境是:它们都没有回答一个核心矛盾——并发连接数可能是成千上万,但一台机器真正能同时执行代码的CPU核心数,却只有个位数或者几十个。如果线程数量和连接数量强绑定,系统迟早会被压垮。

真正的突破:不问"谁准备好了",而是"谁刚刚做完"

Windows NT内核团队给出的答案是IOCP——I/O完成端口,随Windows NT 3.5于1994年正式发布。它的设计哲学,和后来Unix世界主流的select、poll、epoll有一个根本性的分歧,理解这个分歧,是理解IOCP为什么特别的关键。

Unix世界的主流模型,本质上是**"就绪通知"(Readiness Notification)**:应用程序问操作系统,"这些socket里,哪些现在已经可以读或者可以写了?",得到答案后,应用程序自己去执行真正的读写操作。

而IOCP走的是完全不同的路——"完成通知"(Completion Notification):应用程序直接发起一次异步的读或写请求(这被称为Overlapped I/O,重叠I/O),然后立刻返回去做别的事情,由操作系统内核在后台真正完成这次数据搬运,等数据已经读好、或者已经写完之后,内核才把"这件事已经做完了"的通知,投递到一个叫"完成端口"的内核队列里。

这个设计和Dave Cutler此前在DEC VMS系统上的经验一脉相承——VMS本身就有相当成熟的异步I/O完成机制,Cutler把这套思路带进了Windows NT的内核设计中。IOCP真正巧妙的地方在于它同时解决了两个问题:第一,应用程序不再需要为每个连接分配一个专属线程——发起异步I/O之后线程立刻释放,可以去处理别的连接;第二,完成端口允许你自己控制"到底应该有多少个线程在同时处理这些完成通知",微软给出的经典实践建议是——工作线程数量应该和CPU核心数大致匹配,多个线程共享同一个完成端口,谁空闲了,就去队列里取下一个已经完成的I/O任务来处理。这就从根本上把"并发连接数"和"实际工作线程数"这两个变量彻底解耦了。

源码里的体现

IOCP的编程模型核心,浓缩在两个函数调用里:CreateIoCompletionPort用于创建完成端口,并把一个个socket或者文件句柄"关联"到这个端口上;而工作线程只需要反复调用GetQueuedCompletionStatus,这个调用会阻塞在这里,直到内核队列里出现一个已经完成的I/O操作,线程被唤醒,拿到这个完成结果,处理完业务逻辑后,再回来继续调用这个函数等待下一个任务。

这段代码背后最值得玩味的设计,是完成端口内部维护的先进先出队列,加上一个"并发值"参数——你可以在创建端口时指定,同一时刻最多允许多少个线程真正处于"运行"状态(通常设为CPU核心数),当某个正在运行的线程因为其他原因阻塞时,内核会智能地唤醒队列里等待的下一个线程来补位,尽可能让CPU核心始终保持"满载但不过载"的状态。这本质上是把"如何合理调度线程去匹配CPU资源"这件极其复杂的事情,直接下沉进了内核里完成,而不是交给应用程序自己摸索。

设计思想

IOCP的设计浓缩了几种在高性能系统里反复出现的核心思想:

  • 完成驱动而非就绪驱动:不问"能不能做",而是让内核直接把"已经做完"的结果送到你面前,减少了应用层需要主动轮询和调度的复杂度。

  • 线程池思想,与连接数彻底解耦:并发连接数可以是几万,工作线程数量却始终稳定地贴合CPU核心数量。

  • 内核级别的负载均衡:把线程调度的精细决策,交给最了解硬件状态的内核,而不是应用层自己去猜。

  • 零拷贝的延伸空间:重叠I/O的异步模型,天然为后续结合DMA、分散/聚集(Scatter-Gather)等零拷贝技术留出了空间。

为什么它最终赢了?

IOCP之所以在Windows生态里长期保持"没有真正对手"的地位,是因为它一次性解决了高并发服务器最核心的两个痛点——既不需要为每个连接付出一个线程的代价,又能让有限的CPU核心得到充分且不过载的利用。

这套模型此后成为Windows高性能网络服务的事实标准:IIS(Internet Information Services)、SQL Server的网络层,长期基于IOCP构建;.NET的异步I/O体系、包括后来的async/await语法糖,底层在Windows平台上很大程度依赖IOCP提供的异步能力;跨平台的libuv(Node.js的底层事件循环库)在Windows平台上,专门用IOCP作为其异步I/O的实现后端,与Linux平台上使用epoll的实现分庭抗礼;Rust生态里的异步运行时Tokio,同样在Windows上基于IOCP构建其底层驱动。

它真正改变的,是"高并发网络编程"这件事在Windows世界里的默认答案——不再需要工程师自己去纠结线程池大小该怎么调、连接数暴涨了该怎么办,这些复杂度被系统性地下沉进了操作系统内核这一层。

有没有更好的方案?

耐人寻味的是,Linux世界这些年也在朝着IOCP当年的方向靠拢。2019年,Linux内核开发者Jens Axboe提出了io_uring,这是Linux异步I/O历史上一次真正意义上的范式转变——它同样采用了"完成队列"的设计,用户态和内核态共享一片环形缓冲区,应用程序提交I/O请求,内核完成后把结果写入完成队列,用户态几乎不需要额外的系统调用开销就能拿到结果。这本质上就是**"完成驱动"哲学在Linux世界的一次迟到二十多年的回归**——某种意义上,这是对IOCP当年设计理念的一次隔空致敬(尽管两者在具体实现细节上有相当大的差异,io_uring更进一步利用了共享内存环减少系统调用次数)。

更现代的多核架构、更强调低延迟的NVMe存储设备,让"减少系统调用次数、减少内核态用户态切换"变得越来越重要,这也是io_uring相比传统epoll更进一步的核心动机之一。而在编程语言层面,Rust的async/await、Go的goroutine调度器、Java 21引入的Virtual Thread(虚拟线程),都在用不同的方式,试图把"高并发编程"这件事的心智负担,从工程师手中进一步转移给运行时和调度器——这条路径上,IOCP当年"让内核帮你管理线程和I/O完成"的思路,可以说是一次相当早期的先声。

现实中的应用

  • IIS(Internet Information Services):微软自家Web服务器,网络层长期基于IOCP构建。

  • SQL Server:数据库引擎的网络通信层同样依赖IOCP实现高并发连接处理。

  • .NET/.NET Core:异步I/O与async/await编程模型在Windows平台上的底层实现基础之一。

  • libuv(Node.js):在Windows平台专门使用IOCP作为异步事件循环的后端实现。

  • Tokio(Rust异步运行时):跨平台异步运行时在Windows上同样基于IOCP构建其I/O驱动。

这些系统的共同选择,反映出一个朴素的事实:只要你需要在Windows平台上构建高并发、高吞吐的网络服务,IOCP几乎始终是那个绕不开的底层答案。

本内容由作者授权发布,观点仅代表作者本人,不代表虎嗅立场。如对本稿件有异议或投诉,请联系 tougao@huxiu.com。

本文来自虎嗅,原文链接:https://www.huxiu.com/article/4880691.html?f=wyxwapp

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
八路军六个师长中,仅萧克未能评上元帅,毛主席感叹:委屈你了!

八路军六个师长中,仅萧克未能评上元帅,毛主席感叹:委屈你了!

大运河时空
2026-09-10 15:10:03
韩旭将重返纽约!中国女篮出征亚运会:刘禹彤回归 王思雨继续带伤鏖战

韩旭将重返纽约!中国女篮出征亚运会:刘禹彤回归 王思雨继续带伤鏖战

颜小白的篮球梦
2026-09-11 11:26:48
美剧神作排行榜

美剧神作排行榜

喜欢历史的阿繁
2026-09-11 00:50:02
杭州地方国企疯狂财务造假,多项业务纯属虚构,时任董事长已被查办

杭州地方国企疯狂财务造假,多项业务纯属虚构,时任董事长已被查办

大风新闻
2026-09-11 09:20:02
不惯着!解放军直接开火示警!

不惯着!解放军直接开火示警!

叶葉夜
2026-09-11 13:40:51
拿牌有戏!中国U23完胜乌兹别克斯坦:3细节让人太惊喜

拿牌有戏!中国U23完胜乌兹别克斯坦:3细节让人太惊喜

邱泽云
2026-09-11 14:11:28
4岁男童“摸臀门”事件彻底失控,女主角果然不简单!

4岁男童“摸臀门”事件彻底失控,女主角果然不简单!

脆皮先生
2026-09-10 21:24:50
为什么现在还有那么多人坚持认为:中国的改革开放只有少数人得利?

为什么现在还有那么多人坚持认为:中国的改革开放只有少数人得利?

非虚构人间
2026-09-10 20:54:21
中国妇女报谈“低保女孩看演唱会”舆情:困难家庭孩子同样值得拥有适度的小美好、小热爱,但个人自由有边界,期待年轻人懂得责任与分寸

中国妇女报谈“低保女孩看演唱会”舆情:困难家庭孩子同样值得拥有适度的小美好、小热爱,但个人自由有边界,期待年轻人懂得责任与分寸

上观新闻
2026-09-11 10:37:20
上海体育局给刘翔5个选择! 名记:哪个都不错 但他一个都没看上

上海体育局给刘翔5个选择! 名记:哪个都不错 但他一个都没看上

念洲
2026-09-11 08:14:39
8个在家挣钱的方法,只要不懒,每月多挣几千,就算失业也不怕

8个在家挣钱的方法,只要不懒,每月多挣几千,就算失业也不怕

小陆搞笑日常
2026-09-09 08:18:05
难怪怒怼上海体育局,终身合同仅皮毛,刘翔还有条鲜为人知的后路

难怪怒怼上海体育局,终身合同仅皮毛,刘翔还有条鲜为人知的后路

呀古铜
2026-08-29 10:36:55
富养女没人敢接盘了,越来越多的大龄剩女家庭已经扛不住了

富养女没人敢接盘了,越来越多的大龄剩女家庭已经扛不住了

流苏晚晴
2026-09-11 13:48:31
其实,很多人低估了一万块的威力

其实,很多人低估了一万块的威力

AI读书
2026-09-11 16:08:43
特朗普承诺,如果中期选举赢了,将向所有美国成年人每人发5000美元,财长贝森特台下鼓掌

特朗普承诺,如果中期选举赢了,将向所有美国成年人每人发5000美元,财长贝森特台下鼓掌

极目新闻
2026-09-10 15:27:14
刘翔再次硬刚毫不留情,所得100万分文不取全捐出,官方通报惹巨大争议

刘翔再次硬刚毫不留情,所得100万分文不取全捐出,官方通报惹巨大争议

球盲百小易
2026-09-10 18:01:10
性专家说:当一个异性开口跟你要钱,要礼物,不管对方是不是想试探你的真心,你都应该明白,你已被对方列入供养者行列

性专家说:当一个异性开口跟你要钱,要礼物,不管对方是不是想试探你的真心,你都应该明白,你已被对方列入供养者行列

心理观察局
2026-08-05 06:46:04
软通动力与字节跳动旗下Flinco达成战略合作

软通动力与字节跳动旗下Flinco达成战略合作

界面新闻
2026-09-11 10:37:53
涨价1000元依旧疯抢!iPhone 18 Pro系列明天预售:预约量突破350万

涨价1000元依旧疯抢!iPhone 18 Pro系列明天预售:预约量突破350万

快科技
2026-09-11 15:09:08
刘翔这次晒出18双运动鞋!这不是在炫耀,而是他夺冠的来时路,网友:冠军的下半场,远比赛场艰难

刘翔这次晒出18双运动鞋!这不是在炫耀,而是他夺冠的来时路,网友:冠军的下半场,远比赛场艰难

火山詩话
2026-09-11 09:03:04
2026-09-11 16:51:00
虎嗅APP incentive-icons
虎嗅APP
个性化商业资讯与观点交流平台
27747文章数 688063关注度
往期回顾 全部

科技要闻

罗永浩连用7个“抄的”吐槽苹果折叠屏

头条要闻

"男子称停资助遭受助学生质问"疑反转 民政局查无此人

头条要闻

"男子称停资助遭受助学生质问"疑反转 民政局查无此人

体育要闻

37岁还能场场进球,还能翻跟头!

娱乐要闻

黄晓明直言帮太多白眼狼,杨颖遭殃

财经要闻

千叶珠宝创始人夫妇失联 股价应声"腰斩"

汽车要闻

买菜车也有小乐趣 风云T7不止是台合格家用SUV

态度原创

艺术
数码
旅游
亲子
公开课

艺术要闻

梅尔尼科夫:全山石、苏高礼、林岗等的老师

数码要闻

友通推工业ITX主板ARH171/ARH173,支持"MTL" "ARL"处理器

旅游要闻

阿塞拜疆旅游局官员:阿中旅游合作富有成效

亲子要闻

潮州新时代月子中心婴儿护理口碑怎么样?

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版