【Linux】高并发服务器的起点:五种 IO 模型与非阻塞 IO 本质解析

【Linux】高并发服务器的起点:五种 IO 模型与非阻塞 IO 本质解析

文章目录

高并发服务器的起点:五种 IO 模型与非阻塞 IO 本质解析

💬 开篇:如果你已经掌握了 socket 编程的基础,能写出一个简单的 TCP 服务器,那恭喜你——你已经站在了 Linux 网络编程进阶的门口。打开这扇门,迎接你的是一个关于"等待"和"效率"的哲学命题:当网络数据还没来的时候,程序该干什么?
这篇文章就是回答这个问题的。我们会从五种 IO 模型的本质讲起,深入分析同步/异步、阻塞/非阻塞这四个容易搞混的概念,最后落地到 fcntl 实现非阻塞 IO 的完整代码。理解了这篇,后面的 select、poll、epoll 才能真正学进去。

👍 点赞、收藏与分享:IO 模型是 Linux 后端开发和高性能服务器的必考点,搞懂了这里,面试官问你"说说 epoll 的工作原理"时,你就能从根上讲清楚,而不只是背几个结论。

🚀 循序渐进:我们先从一个钓鱼的故事开始,把五种 IO 模型讲透彻;再辨析同步/异步、阻塞/非阻塞这四个概念;最后动手实现非阻塞 IO,为后续的多路复用打好基础。

一、从钓鱼说起:五种 IO 模型全景图

1.1 IO 的本质:等待 + 拷贝

在展开五种模型之前,我们先搞清楚一件事:一次 IO 操作,到底发生了什么?

无论是读取网络数据、读文件,还是读标准输入,本质上都分两个阶段:

 阶段一:等待数据就绪 数据在网卡/磁盘/键盘上还没到达,内核在等 ↓ 阶段二:数据拷贝 内核把就绪的数据从内核缓冲区拷贝到用户缓冲区 

这两个阶段缺一不可。五种 IO 模型的区别,就在于这两个阶段是怎么处理的。

一个关键结论先记住:等待消耗的时间,往往远远大于拷贝消耗的时间。 所以让 IO 更高效的核心办法,就是让等待的时间尽量少。五种模型的演化,都是围绕这一点展开的。


1.2 钓鱼故事:五种模型的生动类比

假设你要去钓鱼。鱼什么时候咬钩,你不知道(就像网络数据什么时候来,你也不知道)。

1. 阻塞 IO(Blocking IO)

你把鱼竿插进水里,然后就坐在那里等,哪都不去,直到鱼咬钩。

这就是阻塞 IO:调用 read() 之后,如果数据还没来,进程/线程就被挂起(阻塞),什么也干不了,直到内核把数据准备好,拷贝完成,read() 才返回。

 你的程序 内核 |||--- read() 系统调用 ----->||| 等待数据到来... |(程序阻塞在这)||| 数据到了!开始拷贝 |||<--- 拷贝完成,返回 -------|||

特点

  • 所有套接字默认都是阻塞模式
  • 最简单、最常见
  • 缺点是一个线程只能盯着一个 IO,效率低下

2. 非阻塞 IO(Non-blocking IO)

你把鱼竿插进水里,每隔几秒就过来看一眼,没咬钩就去旁边玩,再回来看,周而复始。

这就是非阻塞 IO:调用 read() 时如果数据还没准备好,内核直接返回一个错误码 EWOULDBLOCK,而不是让你等。程序可以继续干别的事,但需要不断地重复调用(轮询,polling)。

 你的程序 内核 |||--- read() ----------->||<-- EWOULDBLOCK ------ | 数据还没来 |||--- read() ----------->||<-- EWOULDBLOCK ------ | 数据还没来 |||--- read() ----------->||| 数据来了!拷贝中... |<-- 返回数据 ---------- |

特点

  • 需要程序主动轮询,消耗 CPU(CPU 一直在问"好了吗?好了吗?")
  • 一般只在特定场景下使用,不推荐单独使用

3. 信号驱动 IO(Signal-driven IO)

你在鱼竿上装一个铃铛,鱼咬钩时铃铛会响,你才过来处理。

这就是信号驱动 IO:程序向内核注册一个信号处理函数(SIGIO),然后继续干别的事。当数据准备好时,内核发送 SIGIO 信号通知程序,程序收到信号后再去调用 read() 把数据取走。

 你的程序 内核 ||| 注册 SIGIO 信号处理函数 ||---告诉我数据来了--------->||||(程序继续干其他事)| 等待数据... |||| 数据来了!发信号 |<== SIGIO 信号 ===========||||--- read() ----------->||<-- 拷贝完成,返回 ------ |

特点

  • 等待阶段不阻塞,比较灵活
  • 但在 TCP 中,信号触发情况复杂(各种事件都会触发),实际使用较少

4. IO 多路转接(IO Multiplexing)

你同时放了 100 根鱼竿,然后雇了一个管理员(select哪根咬钩了就通知你去处理哪根。)

这就是 IO 多路转接,也叫 IO 多路复用(multiplexing)。这才是高性能服务器的核心技术。

 你的程序 内核 ||| select/epoll_wait()||--- 监控 fd1,fd2...fd100->||| 等待任一 fd 就绪 |(程序阻塞在 select)||| fd5 就绪了! |<--- 返回就绪的 fd --------|||| 对 fd5 调用 read()||--- read(fd5) ---------->||<-- 拷贝完成,返回 --------|

特点

  • 一个进程能处理大量连接(这就是 C10K 问题的解决思路)
  • select/poll/epoll 是三种实现,后面我们会详细讲
  • 注意:select 本身是阻塞的,但它能同时监控多个 fd,解决了"一次只能等一个"的问题

5. 异步 IO(Asynchronous IO)

你委托一个全职助手去钓鱼:鱼咬钩、收杆、处理、放进冰箱,全流程都由助手完成,最后只通知你“鱼已经在冰箱里了”。
程序发起 IO 请求后立刻返回,内核负责等待数据就绪 + 完成数据拷贝到用户缓冲区,全部完成后再通过信号/回调/事件通知程序:数据已经可以直接用了。

与信号驱动 IO 的关键区别:

  • 信号驱动:内核告诉你“可以开始读了”,你自己 read() 完成拷贝
  • 异步 IO:内核告诉你“已经拷贝好了”,你直接用缓冲区数据
 你的程序 内核 ||| aio_read()||--- 发出 IO 请求,立即返回->||||(程序继续干其他事)| 等待数据 + 拷贝... |||| 全部完成!通知程序 |<== 回调/信号 ============|||| 直接使用缓冲区里的数据 |

异步 IO 是最彻底的非阻塞,两现复杂,Linux 下的 aio 支持有限。


1.3 五比

IO 模型等待阶段拷贝阶段典型接口适用场景
阻塞 IO阻塞阻塞read/write简单场景,连接数少
非阻塞 IO不阻塞(轮询)阻塞read + O_NONBLOCK配合 IO 多路复用使用
信号驱动 IO不阻塞(信号通知)阻塞SIGIO使用较少
IO 多路转接阻塞(但监控多个)阻塞select/poll/epoll高并发服务器首选
异步 IO不阻塞不阻塞aio_read/aio_write最彻底,但实现复杂
 五种 IO 模型的本质区别: 等待阶段 拷贝阶段 阻塞 IO ████████████████ ████ 非阻塞 IO ✓轮询✓轮询✓就绪! ████ 信号驱动 IO ---干其他---SIGIO! ████ IO 多路转接 ████(多个fd)█████ ████ 异步 IO ---干其他---完成!(内核帮你拷)

二、最容易搞混的四个概念

2.1 同步 vs 异步:关注消息通信机制

这两个概念在不同语境下有不同含义,一定要先搞清楚背景。在 IO 模型中:

同步(Synchronous):调用者发出调用后,在没有得到结果之前,调用不返回。调用者主动等待这个调用的结果。

异步(Asynchronous):调用者发出调用后,调用立刻返回,没有返回结果。被调用者通过状态通知或回调函数来告知调用者结果。

重要:这里的"同步/异步"是 IO 通信机制的概念,跟多线程中"同步与互斥"的"同步"完全不是一回事!多线程的同步指的是线程间的协作次序控制,尤其是访问临界资源时的协调。以后看到"同步"这个词,一定先搞清楚大背景!

2.2 阻塞 vs 非阻塞:关注程序等待时的状态

阻塞:调用结果返回之前,当前线程会被挂起。调用线程只有得到结果之后才会返回。

非阻塞:不能立刻得到结果之前,该调用不会阻塞当前线程,直接返回(可能带错误码)。


2.3 四者组合:妖怪蒸唐僧的例子

我们用一个生动的例子来理解这四个概念的组合关系。

妖怪抓到了唐僧,想蒸来吃,锅得烧热。妖怪有几种等法:

阻塞 + 同步(傻等型):
妖怪盯着锅,一直等到锅热,啥也不干。

 妖怪:(盯着锅) 妖怪:(还在盯) 锅:我热了! 妖怪:好,下一步 

非阻塞 + 同步(轮询型):
妖怪每隔一会问一次"热了吗",没热就去玩会儿,再来问。自己主动轮询。

 妖怪:热了吗?(没热)去玩 妖怪:热了吗?(没热)去玩 锅:我热了! 妖怪:(下次来问时)好,下一步 

非阻塞 + 异步(信号通知型):
妖怪干其他事,锅热了让小妖怪来通知它。妖怪收到通知后,自己去检查、处理。

 妖怪:去干别的事了 锅:(通过小妖怪)我热了! 妖怪:(收到通知)我来了,开始下一步 

完全异步(全托管型):
妖怪干别的事,不只是等通知,而是全程托管——连唐僧也让别人处理,做好了通知妖怪来吃。


2.4 从代码角度理解阻塞和非阻塞

来看一个直观的对比:

// 阻塞读取:如果没有数据,程序卡在 read() 这一行 ssize_t n =read(fd, buf,sizeof(buf));// 只有数据来了,才能到达下一行// 非阻塞读取:如果没有数据,立即返回 -1,errno = EWOULDBLOCK ssize_t n =read(fd, buf,sizeof(buf));// fd 设置了 O_NONBLOCKif(n <0&& errno == EWOULDBLOCK){// 数据还没来,稍后重试continue;}// 程序不会被卡住

阻塞就像"你不给我,我就不走";非阻塞就像"你没有就告诉我一声,我先去忙别的"。


三、高级 IO 概念梳理

3.1 高级 IO 的分类

Linux 中,除了基础的阻塞 IO,以下都属于高级 IO:

高级 IO 类型说明
非阻塞 IOfcntl 设置 O_NONBLOCK
记录锁fcntl 的锁功能
IO 多路转接select / poll / epoll
readv / writev分散读 / 聚集写
存储映射 IOmmap
系统 V 流机制较旧的机制

我们这个系列的重点:IO 多路转接(select → poll → epoll → Reactor 模式)


四、fcntl:实现非阻塞 IO 的利器

4.1 fcntl 函数概览

fcntl 是 Linux 下操控文件描述符属性的瑞士军刀,函数原型如下:

#include<unistd.h>#include<fcntl.h>intfcntl(int fd,int cmd,.../* arg */);

根据 cmd 的不同,它有五种功能:

cmd功能
F_DUPFD复制文件描述符
F_GETFD / F_SETFD获取/设置文件描述符标记
F_GETFL / F_SETFL获取/设置文件状态标记 ← 我们用这个
F_GETOWN / F_SETOWN获取/设置异步 IO 所有权
F_GETLK / F_SETLK / F_SETLKW获取/设置记录锁

我们要实现非阻塞 IO,用的是第三种:获取/设置文件状态标记

4.2 fcntl 的工作原理

文件描述符有一套状态标记位图(flags),记录着这个 fd 的各种属性,比如:

  • O_RDONLY:只读
  • O_WRONLY:只写
  • O_RDWR:读写
  • O_NONBLOCK非阻塞 ← 我们要加的
  • O_APPEND:追加写入
  • O_ASYNC:异步 IO

想让一个 fd 变成非阻塞,就是在它的状态位图上加上 O_NONBLOCK 这一位

操作步骤:

  1. F_GETFL:把当前的位图取出来
  2. O_NONBLOCK上去
  3. F_SETFL:把修改后的位图写回去

就像是给 fd 贴一张标签:“以后操作我,不要等,没数据就直接告诉我 EWOULDBLOCK”。


4.3 实现 SetNoBlock 函数

#include<unistd.h>#include<fcntl.h>#include<cstdio>/** * 将文件描述符设置为非阻塞模式 * @param fd 需要设置的文件描述符 */voidSetNoBlock(int fd){// 第一步:获取当前文件状态标记(这是一个位图)int fl =fcntl(fd, F_GETFL);if(fl <0){perror("fcntl F_GETFL");return;}// 第二步:将 O_NONBLOCK 位添加进去(用按位或,不影响其他标志位)// 错误示范:fcntl(fd, F_SETFL, O_NONBLOCK); // 这会清除其他所有标志!int ret =fcntl(fd, F_SETFL, fl | O_NONBLOCK);if(ret <0){perror("fcntl F_SETFL");return;}}
警告F_SETFL 时一定要先 F_GETFL 取出原有标志,再 |O_NONBLOCK
不能直接 fcntl(fd, F_SETFL, O_NONBLOCK),那样会清除 fd 上所有其他的标志位(比如 O_RDWR),后果不可预料。

五、非阻塞 IO 实战:轮询读取标准输入

5.1 场景描述

我们来做一个小实验:把标准输入(fd = 0)设置为非阻塞,然后用循环轮询读取。这能帮我们直观感受非阻塞 IO 的行为。

5.2 完整代码

#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>#include<string.h>/** * 将指定文件描述符设置为非阻塞模式 */voidSetNoBlock(int fd){int fl =fcntl(fd, F_GETFL);if(fl <0){perror("fcntl F_GETFL");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);}intmain(){// 把标准输入 (fd=0) 设为非阻塞SetNoBlock(0);while(1){char buf[1024]={0};// 非阻塞 read:没有输入时立即返回 -1ssize_t read_size =read(0, buf,sizeof(buf)-1);if(read_size <0){// errno == EWOULDBLOCK 或 EAGAIN 表示"暂时没有数据,稍后重试"// 这是非阻塞 IO 的"正常"情况,不是真正的错误if(errno == EWOULDBLOCK || errno == EAGAIN){printf("[轮询] 没有输入,等 1 秒后重试...\n");sleep(1);continue;}// 其他错误才是真正的错误perror("read");sleep(1);continue;}if(read_size ==0){// 返回 0 表示 EOF(对于标准输入,就是 Ctrl+D)printf("检测到 EOF,退出\n");break;} buf[read_size]='\0';printf("[输入] %s\n", buf);}return0;}

5.3 运行效果分析

编译并运行:

gcc nonblock_stdin.c -o nonblock_stdin ./nonblock_stdin 

运行后的行为:

  • 如果你不输入任何内容,程序每秒打印一次"没有输入,等 1 秒后重试…"
  • 你输入 hello 并回车,程序立刻打印 [输入] hello
  • Ctrl+D,程序退出

这个例子揭示了非阻塞 IO 的两个关键点:

1. EWOULDBLOCK / EAGAIN 不是真正的错误

EWOULDBLOCK 和 EAGAIN 在现代 Linux 上是同一个值 含义:操作会阻塞,但 fd 是非阻塞的,所以直接返回了 处理方式:重试!这是预期内的情况 

2. 非阻塞轮询非常浪费 CPU

如果你把 sleep(1) 去掉,这个程序会以 CPU 100% 的速度狂转,不停地询问"有数据了吗"。这就是非阻塞 IO 单独使用的问题——轮询会浪费大量 CPU

所以,非阻塞 IO 通常不单独使用,而是配合 IO 多路转接(select/poll/epoll)一起用。后者告诉你哪个 fd 有数据了,你再去读——既不浪费 CPU 等待,也不浪费 CPU 轮询。

注意:在终端下,标准输入默认按“行”提交(回车才会把这一行交给程序),所以你看到的是回车后 read 才读到数据;如果改成 raw模式(termios),才可能按键级别返回。

六、IO 流程可视化:从系统调用到数据

6.1 网络 IO 的完整路径

理解 IO 模型,还需要知道数据是如何从网卡到达你的程序的:

 网络数据到达的完整路径 远端主机 || 发送数据包 ↓ [网卡 NIC]|| 硬件中断 / DMA ↓ [内核接收缓冲区] ← 数据"就绪"就是指到这里 || 系统调用(read/recv) ↓ [用户空间缓冲区] ← 你的 buf[1024]|| 程序处理 ↓ [你的业务逻辑]

理解了这个路径,五种 IO 模型的区别就更清晰了:

  • 等待阶段:等数据从网卡到达内核缓冲区
  • 拷贝阶段:把数据从内核缓冲区拷贝到用户缓冲区

6.2 为什么 IO 多路转接最适合高并发服务器

假设你的服务器有 10000 个客户端连接:

传统方法(一连接一线程)

线程 1:阻塞等 客户端1 的数据 线程 2:阻塞等 客户端2 的数据 ... 线程 10000:阻塞等 客户端10000 的数据 
  • 10000 个线程!内存开销巨大,上下文切换开销大
  • 大部分时候只有少数客户端在活跃,其他线程都在白白睡觉

IO 多路转接(单线程/少量线程 + epoll)

1 个线程: epoll_wait() 监控 10000 个 fd ↓ 某几个 fd 就绪了 处理这几个 fd ↓ 回到 epoll_wait() 继续监控 
  • 只用 1 个(或少量)线程
  • 只处理真正有数据的连接,不浪费
  • 这就是 Nginx、Redis 的核心原理

七、常见问题与概念辨析

7.1 容易混淆的点

1. IO 多路转接 vs 异步 IO,谁更高效?

很多人以为异步 IO 最好,其实不一定。

  • IO 多路转接(特别是 epoll)在 Linux 上非常成熟,性能极好
  • 异步 IO(aio)在 Linux 上的支持相对有限,且编程复杂度更高
  • Nginx、Redis、Node.js 都基于 IO 多路转接,没有用异步 IO
结论:epoll + 非阻塞 IO 是目前 Linux 高性能服务器的主流方案。
非常适合:连接数多、但同一时刻真正活跃的连接比例不高的场景

2. IO 多路转接自身是阻塞的,怎么说它是"非阻塞"?

select/poll/epoll_wait 本身是阻塞的(如果没有 fd 就绪,会等待)。

但它的价值不在于"不阻塞",而在于"一次监控多个 fd,只要有一个就绪就返回"。

这让一个线程能服务大量连接,而不是为每个连接开一个线程阻塞等待。


3. EAGAIN 和 EWOULDBLOCK 的区别?
// 在 Linux 上,两者通常是同一个值// /usr/include/asm-generic/errno-base.h:#defineEWOULDBLOCKEAGAIN // 通常 EWOULDBLOCK = EAGAIN = 11// 所以处理时,两个都判断就行:if(errno == EAGAIN || errno == EWOULDBLOCK){// 暂时无数据,重试}

4. 为什么 ET 模式(epoll 边缘触发)必须配非阻塞 IO?

这个问题我们在 epoll 那篇会深入讲,这里先埋个伏笔。

简单来说:ET 模式下,数据就绪只通知你一次。如果你用阻塞 read,一次 read 可能没读完所有数据,剩下的数据就再也等不到通知了(ET 不会再次触发)。

所以 ET 模式下,必须用非阻塞 read,循环读直到 EAGAIN,确保把缓冲区的数据一次性读完。


7.2 典型面试题解析

Q:说说 select、poll、epoll 的区别。

(先别急着说,从这篇的基础开始引入)

首先,它们都是 IO 多路转接的实现,核心目的是让一个线程监控多个 fd。区别在于:

  • select:基于位图,有 fd 数量上限(1024/4096),每次都要拷贝整个位图到内核,返回后还要遍历找就绪的 fd
  • poll:解决了 select 的数量限制,用 pollfd 数组,但还是每次都要全量拷贝和遍历
  • epoll:内核维护红黑树和就绪队列,只拷贝变化的 fd,epoll_wait 直接返回就绪的 fd,性能最好

这些我们后面三篇会详细展开。


八、知识点总结

8.1 核心要点

#要点说明
1IO 两阶段等待就绪 + 数据拷贝,等待占大头
2五种模型本质对这两个阶段的不同处理策略
3同步≠阻塞同步/异步关注通信机制,阻塞/非阻塞关注等待状态
4fcntl 设置非阻塞F_GETFL 取出 + O_NONBLOCK+F_SETFL 写回
5EAGAIN 不是错误非阻塞 IO 下"暂无数据"的正常返回,应重试

8.2 概念记忆技巧

记住这张表,面试被问到直接不慌:

同步/异步 → 谁来通知结果(调用者主动等 / 被调用者来通知) 阻塞/非阻塞 → 调用者等待时的状态(挂起 / 继续执行) 五种模型的区别 → 钓鱼故事: 阻塞 = 呆看 信号驱动 = 装铃铛 IO多路转接 = 雇管家同时盯100根竿 异步IO = 全托管,搞好了叫你 

同时:在IO模型里面,同步异步的本质区别还有:

  • 同步 IO:拷贝阶段由用户线程触发(read/recv 去拷贝)
  • 异步 IO:等待+拷贝都由内核完成,完成后通知用户线程

💬 总结:这篇文章我们从最底层的 IO 两阶段模型出发,走通了五种 IO 模型的演进逻辑,厘清了同步/异步、阻塞/非阻塞这四个关键概念,并通过 fcntl 实现了第一个非阻塞 IO 的实战代码。现在你应该能清楚地说出:为什么 IO 多路转接是高并发服务器的基础,以及为什么非阻塞 IO 通常要和多路复用配合使用。下一篇,我们开始深入 select ——历史最悠久的多路转接实现,从它的位图原理到字典服务器的完整实现,一步步拆解。
👍 点赞、收藏与分享:IO 模型是面试高频知识点,也是理解 epoll、Reactor 的基础。如果这篇帮你把这几个概念理清楚了,点个赞再走吧!后面四篇的内容会越来越精彩 💪

Read more

苹果最贵手机要来了!折叠屏iPhone将于9月亮相;部分高校严禁校内使用OpenClaw;黄仁勋预言:传统软件和APP或将消失 | 极客头条

苹果最贵手机要来了!折叠屏iPhone将于9月亮相;部分高校严禁校内使用OpenClaw;黄仁勋预言:传统软件和APP或将消失 | 极客头条

「极客头条」—— 技术人员的新闻圈! ZEEKLOG 的读者朋友们好,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。(投稿或寻求报道:[email protected]) 整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 一分钟速览新闻点! * 多所高校要求警惕 OpenClaw 安全风险,部分严禁校内使用 * 荣耀 CEO 李健:荣耀机器人全栈自研,将聚焦消费市场 * 马化腾凌晨 2 点发声:还有一批龙虾系产品陆续赶来 * 前快手语言大模型中心负责人张富峥,已加入智源人工智能研究院,负责 LLM 方向 * 最新全球 AI 应用百强榜发布,豆包/DeepSeek/千问上榜 * 苹果折叠 iPhone 将于九月亮相,融合 iPhone 与 iPad 体验

By Ne0inhk
不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

编译 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) “如果你周日去旧金山的咖啡馆,会发现几乎每个人都在工作。” 这是 AI 创业公司 Mythril 联合创始人 Sanju Lokuhitige 最近最直观的感受。去年 11 月,他特地搬到旧金山,只为了更接近 AI 创业浪潮的中心。但很快,他也被卷入了这股浪潮带来的另一面——一种越来越极端的工作文化。 Lokuhitige 坦言,他现在几乎每天工作 12 小时,每周 7 天。除了每周少数几场刻意安排的社交活动(主要是为了和创业者们建立联系),其余时间几乎都在写代码、做产品。 “有时候我整整一天都在编程,”他说,“我基本没有什么工作与生活的平衡。”而这样的生活,在如今的 AI 创业圈里并不算罕见。 旧金山 AI 创业圈的真实日常 一位在旧金山一家 AI

By Ne0inhk
黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

AI 究竟是什么?在 NVIDIA CEO 黄仁勋看来,它早已不只是聊天机器人或某个大模型,而是一种正在迅速成形的“新型基础设施”。 近日,黄仁勋在英伟达官网发布了一篇长文,提出一个颇具形象的比喻——AI 就像一块“五层蛋糕”。从最底层的能源,到芯片、基础设施、模型,再到最上层的应用,人工智能正在形成一整套完整的产业技术栈,并像电力和互联网一样,逐渐成为现代社会的底层能力。 这也是黄仁勋自 2016 年以来公开发表的第七篇长文。在这篇文章中,他从计算机发展史与第一性原理出发,试图解释 AI 技术栈为何会演化成如今的形态,以及为什么全球正在掀起一场规模空前的 AI 基础设施建设。 在他看来,过去几十年的软件大多是预先编写好的程序:人类设计好算法,计算机按指令执行,数据被结构化存储在数据库中,通过精确查询调用。而 AI 的出现打破了这一模式——计算机开始能够理解图像、文本和声音,并根据上下文实时生成答案、推理结果甚至新的内容。 正因为智能不再是预先写好的代码,而是实时生成的能力,支撑它运行的整个计算体系也必须被重新设计。

By Ne0inhk
猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 过去几年里,科技公司几乎都在同一件事上加速:让 AI 参与写代码。 从自动补全、自动生成函数,到直接修改系统配置,生成式 AI 已经逐渐走进真实生产环境。但最近发生在亚马逊的一连串事故,却给整个行业泼了一盆冷水——当 AI 开始真正参与生产环境开发时,事情可能远比想象复杂。 最近,多家媒体披露,本周二亚马逊内部紧急召开了一场工程“深度复盘(deep dive)”会议,专门讨论最近频繁出现的系统故障——其中,一个被反复提及的关键词是:AI 辅助代码。 一周 4 次严重事故,亚马逊内部紧急复盘 事情的起点,是最近一段时间亚马逊系统稳定性明显下降。 负责亚马逊网站技术架构的高级副总裁 Dave Treadwell 在一封内部邮件中坦言:“各位,正如大家可能已经知道的,最近网站及相关基础设施的可用性确实不太理想。” 为此,公司决定把原本每周例行举行的技术会议

By Ne0inhk