zoukankan      html  css  js  c++  java
  • I/O Multiplexing

    当多个独立的I/O事件同时发生时,I/O多路复用是一种解决方式。
    为了提高服务器的吞吐量,单个线程通过记录跟踪每个I/O流的状态同时管理多个I/O流,非常类似时分复用技术。
    在这里插入图片描述
    I/O多路复用的具体实现方式有3种:select()poll()epoll()

    select

    select()系统调用:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    select()会一直阻塞直到至少一个文件描述符就绪,可以读写,或者出现异常。
    中间3个参数会被修改,表示哪个FD准备好了,最后一个表示等待时间,NULL表示无限等待。
    返回就绪的FD数目,有错-1。只知道有就绪,不知道哪个FD就绪了。

    int s = socket();
    bind();
    listen();
    
    int fd[];  // 需要监听的socket集合
    while (1) {
    	int n = select();
    	for (int i = 0; i < fd.size(); ++i) {
    		if (FD_ISSET()) {  // 判断哪个socket接收到数据
    			// 处理数据
    		}
    	}
    }
    

    select()是阻塞方法,只有某个socket接收到数据才会继续执行,唤醒进程。
    直接的方式缺点就比较多:

    • 时间开销大,所以规定最多监听1024个socket;
    • 每次调用都要把fd集合从用户态拷贝到内核态。
    • 线程不安全:

    If a file descriptor being monitored by select() is closed in another thread, the result is unspecified.

    poll

    去掉了1024的限制,线程不安全。

    epoll

    线程安全,知道哪个FD就绪,只有Linux支持。
    相比于select()epoll()不会无差别轮询,只处理接收到数据的socket,这样复杂度就降低为(O(k))

    Reference

    I/O多路复用是什么意思

  • 相关阅读:
    vmware Unable to open kernel device "\.Globalvmx86": The system cannot find the file 的解决方法
    nc和telnet配合使用
    linux下批量替换文件内容
    Linux动态库的导出控制
    goang Receiver & interface
    Go与C语言的互操作 cgo
    Go fsm
    Git多账号登陆
    mysql 安装与配置、使用
    Reverse Integer
  • 原文地址:https://www.cnblogs.com/EIMadrigal/p/13558310.html
Copyright © 2011-2022 走看看