IO 模型:阻塞 IO、非阻塞 IO 和 IO 多路复用

举报
William 发表于 2025/02/11 09:27:03 2025/02/11
【摘要】 IO 模型:阻塞 IO、非阻塞 IO 和 IO 多路复用 介绍在计算机网络编程中,IO 模型负责处理数据传输和接收的方式。主要有以下几种模型:阻塞 IO (Blocking IO):经典的同步 IO 模型,调用者在请求完成前会一直被阻塞。非阻塞 IO (Non-blocking IO):调用者发出请求后立即返回,通过轮询机制检查是否准备好读/写操作。IO 多路复用 (IO Multiple...

IO 模型:阻塞 IO、非阻塞 IO 和 IO 多路复用

介绍

在计算机网络编程中,IO 模型负责处理数据传输和接收的方式。主要有以下几种模型:

  1. 阻塞 IO (Blocking IO)
    经典的同步 IO 模型,调用者在请求完成前会一直被阻塞。

  2. 非阻塞 IO (Non-blocking IO)
    调用者发出请求后立即返回,通过轮询机制检查是否准备好读/写操作。

  3. IO 多路复用 (IO Multiplexing)
    使用一种机制(如 selectpollepoll)来监听多个 IO 描述符,以便同时监控多个输入流。

应用使用场景

  • 阻塞 IO:简单的单线程应用,如命令行程序。
  • 非阻塞 IO:需要低延迟响应的应用,如游戏开发。
  • IO 多路复用:高并发服务器,如 Web 服务器。

原理解释

阻塞 IO

  • 调用者发起 IO 操作,然后等待直到操作完成。
  • 简单易用,但效率不高,尤其是在处理高并发时。

非阻塞 IO

  • 调用者发起 IO 操作,如果数据未准备好则立即返回。
  • 通常需要不断轮询以检查操作是否完成。

IO 多路复用

  • 调用者使用一个系统调用来等待多个 IO 操作的完成。
  • 一旦任何一个操作准备好,调用者就会被通知。
  • 常用于处理大量连接,如聊天室或 Web 服务器。

算法原理流程图

阻塞 IO

+-------------------+
| 发起 IO 请求      |
+--------+----------+
         |
         v
+--------+----------+
|  阻塞等待结果     |
+--------+----------+
         |
         v
+--------+----------+
|  处理结果         |
+-------------------+

非阻塞 IO

+-------------------+
| 发起 IO 请求      |
+--------+----------+
         |
         v
+--------+----------+
| 检查状态          |
+--------+----------+
|  ||  v
|  处理结果
|
+--------+----------+
| 否,轮询再次检查  |
+-------------------+

IO 多路复用

+-------------------+
| 注册多个 IO       |
+--------+----------+
         |
         v
+--------+----------+
| 等待任意 IO 准备  |
+--------+----------+
         |
         v
+--------+----------+
|  处理准备好的 IO  |
+-------------------+

实际详细应用代码示例实现

Python 示例

阻塞 IO
import socket

def blocking_io():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('localhost', 8080))
    server.listen(1)

    conn, addr = server.accept()  # 阻塞等待连接
    data = conn.recv(1024)        # 阻塞等待数据
    print(f'Received: {data}')
    conn.close()

blocking_io()
非阻塞 IO
import socket

def non_blocking_io():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setblocking(False)  # 设置为非阻塞模式
    server.bind(('localhost', 8080))
    server.listen(1)

    while True:
        try:
            conn, addr = server.accept()
            data = conn.recv(1024)
            if data:
                print(f'Received: {data}')
                conn.close()
                break
        except BlockingIOError:
            continue

non_blocking_io()
IO 多路复用
import socket
from select import select

def io_multiplexing():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('localhost', 8080))
    server.listen(5)

    inputs = [server]
    while True:
        readable, _, _ = select(inputs, [], [])
        for s in readable:
            if s is server:
                conn, addr = server.accept()
                inputs.append(conn)
            else:
                data = s.recv(1024)
                if data:
                    print(f'Received: {data}')
                inputs.remove(s)
                s.close()

io_multiplexing()

测试步骤以及详细代码、部署场景

  1. 安装 Python 环境

    • 确保已安装 Python 3.x。
  2. 运行相应代码

    • 将示例分别保存至不同的 .py 文件,逐个运行观察行为。
  3. 测试客户端连接

    • 使用 telnet 或其他工具连接到 localhost:8080 进行测试。
  4. 验证行为

    • 确认不同 IO 模型的运行效果,根据需求选择合适的模型。

材料链接

总结

不同的 IO 模型适用于不同的应用场景。阻塞 IO 简单易用,但在高并发环境下效率较低;非阻塞 IO 提供了更快的响应,但需要复杂的管理逻辑;而 IO 多路复用是高并发服务器的主流方案之一,结合了良好的性能与可扩展性。

未来展望

随着硬件技术的发展和多核 CPU 的普及,异步 IO 和事件驱动编程将越来越流行。同时,新的 IO 模型(如 IO_uring)在 Linux 上的兴起,也显示出对高效 IO 需求的持续增长。未来,跨平台高效异步 IO 框架可能成为主流,进一步推动大规模并发应用的发展。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。