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

两种系统哲学的分野:为什么 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.

相关推荐
热点推荐
自取其辱!C罗抢在梅西告别赛前发布声明 结果变成了丑陋滑稽表演

自取其辱!C罗抢在梅西告别赛前发布声明 结果变成了丑陋滑稽表演

雪狼侃体育
2026-10-07 12:37:36
华为余承东:极紫外光刻(EUV)设备是制造先进芯片的关键,国内目前正在研发

华为余承东:极紫外光刻(EUV)设备是制造先进芯片的关键,国内目前正在研发

IT之家
2026-10-07 21:34:10
郑钦文战胜本届中网“最大黑马”,用胜利作为24岁生日礼物

郑钦文战胜本届中网“最大黑马”,用胜利作为24岁生日礼物

澎湃新闻
2026-10-07 21:44:05
教育竟突然松绑了!真正原因在这里

教育竟突然松绑了!真正原因在这里

行者殷涛
2026-10-06 18:12:56
82岁独享2026诺贝尔物理学奖,奖金超800万,他说:希望这个奖能帮我的新提案过关

82岁独享2026诺贝尔物理学奖,奖金超800万,他说:希望这个奖能帮我的新提案过关

科普中国
2026-10-07 15:25:48
欠薪2300万元!估值140亿的机器人巨头,如今连工资都发不出来了

欠薪2300万元!估值140亿的机器人巨头,如今连工资都发不出来了

李砍柴
2026-10-07 18:56:23
地雷风波升级,金与正发声:野兽都不能进进出出

地雷风波升级,金与正发声:野兽都不能进进出出

中国新闻周刊
2026-10-07 16:43:44
官宣!西班牙传奇中场,签约中国联赛,退役3年后复出加盟港超

官宣!西班牙传奇中场,签约中国联赛,退役3年后复出加盟港超

小金体坛大视野
2026-10-07 21:42:12
女子买的二手房楼顶有座坟,就在客厅正上方,买房多年毫不知情;邻居:2009年埋着病逝7岁男童;警方已取走尸骨作进一步鉴定

女子买的二手房楼顶有座坟,就在客厅正上方,买房多年毫不知情;邻居:2009年埋着病逝7岁男童;警方已取走尸骨作进一步鉴定

都市快报橙柿互动
2026-10-08 00:14:49
梅西更新社媒,C罗评论:致敬你随阿根廷队所取得的一切成就

梅西更新社媒,C罗评论:致敬你随阿根廷队所取得的一切成就

懂球帝
2026-10-08 02:42:02
美媒:转移近2亿美元政府资金购买黄金和豪宅等资产,美CIA前官员认罪

美媒:转移近2亿美元政府资金购买黄金和豪宅等资产,美CIA前官员认罪

环球网资讯
2026-10-07 17:42:12
比亚迪车顶光伏实测:晒8小时充4度电,你们说这8000块花得值不值

比亚迪车顶光伏实测:晒8小时充4度电,你们说这8000块花得值不值

音乐时光的娱乐
2026-10-07 16:27:20
卫健委已将左氧氟沙星列为重点监控药物!提醒:服用千万注意

卫健委已将左氧氟沙星列为重点监控药物!提醒:服用千万注意

健康科普365
2026-10-07 11:35:08
不男不女,娘性文化?人民日报“点名”周深,身份地位回不去了

不男不女,娘性文化?人民日报“点名”周深,身份地位回不去了

不似少年游
2026-10-07 09:32:51
为什么一定要拼尽全力考上985、211?不是为了高人一等,是为了以后不用向生活低头

为什么一定要拼尽全力考上985、211?不是为了高人一等,是为了以后不用向生活低头

好爸育儿
2026-10-07 11:07:25
时隔两年重返中网八强!郑钦文2-1力克查拉耶娃 连续4轮鏖战三盘

时隔两年重返中网八强!郑钦文2-1力克查拉耶娃 连续4轮鏖战三盘

醉卧浮生
2026-10-07 21:22:50
高市早苗对华重磅改口,一名39岁女性的生命换来的?

高市早苗对华重磅改口,一名39岁女性的生命换来的?

健身狂人
2026-10-06 04:25:10
俄官方称鼠疫研究机构一名员工确诊“不明原因肺炎”

俄官方称鼠疫研究机构一名员工确诊“不明原因肺炎”

界面新闻
2026-10-07 20:32:28
出现第二例死亡,应全力施压俄罗斯共享鼠疫信息

出现第二例死亡,应全力施压俄罗斯共享鼠疫信息

黔有虎
2026-10-07 20:03:37
巴萨发文致敬佩德罗:你永远是历史一部分

巴萨发文致敬佩德罗:你永远是历史一部分

懂球帝
2026-10-07 19:53:12
2026-10-08 06:55:00
虎嗅APP incentive-icons
虎嗅APP
个性化商业资讯与观点交流平台
27916文章数 688110关注度
往期回顾 全部

科技要闻

诺贝尔化学奖揭晓,两位科学家摘得大奖

头条要闻

中国新婚夫妇在马尔代夫度假溺亡 有人1天目睹2起溺水

头条要闻

中国新婚夫妇在马尔代夫度假溺亡 有人1天目睹2起溺水

体育要闻

从骑马舞到开口全中文 德约在北京不止七冠

娱乐要闻

蔡康永风波再升级!这次谁也救不了他

财经要闻

谷歌签下科技史上最大核能协议

汽车要闻

智能化再提升 2027款东风标致、东风雪铁龙新车更人性化了

态度原创

本地
亲子
教育
房产
军事航空

本地新闻

中秋逛白塔寺,体验国医妙荟雅集

亲子要闻

赴美生子曾经很流行,5年暴涨过20倍,现在这些孩子怎么样了?

教育要闻

走进上海一年花费30万的私立学校

房产要闻

保利大爆发,冲到榜一!海南楼市前三季度,热销榜出炉!

军事要闻

外舰跟监遵义舰 结果自己先"趴窝"了

无障碍浏览 进入关怀版