同步和异步、阻塞和非阻塞

同步和异步、阻塞和非阻塞

        • (1) 同步和异步
        • (2) 阻塞和非阻塞
        • (3)I/O多路复用
        • (4)I/O多路复用使用的场合
        • (5)select
          • (5.1) select 运行原理
          • (5.2) select 优缺点:
        • (6) poll
          • (6.1) poll 运行原理
          • (6.2) poll 优缺点
        • (7) epoll
          • (7.1) epoll 运行原理
          • (7.2) epoll 优缺点
          • (7.3) ET和LT
          • (7.4) epoll读到一半又有新事件来了怎么办

(1) 同步和异步

同步和异步关注的是消息通信机制

  • 同步,是指在发出一个调用时,在没有得到结果之前,该调用就不返回
  • 异步,是指在发出一个调用之后,这个调用就直接返回了,所以没有携带调用结果

(2) 阻塞和非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

  • 阻塞:指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回
  • 非阻塞:调用不能立刻得到结果之前,该调用不会阻塞当前进程。

(3)I/O多路复用

I/O多路复用指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流.

  • I/O 多路复用技术是为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,使进程不阻塞于某个特定的 I/O 系统调用。
      select,poll,epoll都是I/O多路复用的机制。I/O多路复用通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪,就是这个文件描述符进行读写操作之前),能够通知程序进行相应的读写操作。

(4)I/O多路复用使用的场合

  • 当客户处理多个描述符时,必须使用I/O多路复用
  • tcp服务器既要处理监听套接字,又要处理已连接套接字,一般使用I/O多路复用
  • 如果一个服务器要处理多个服务时,一般使用I/O多路复用

(5)select

(5.1) select 运行原理

select把所有监听的文件描述符拷贝到内核中,挂起进程,当某个文件描述符可读或者可写时,中断程序唤起进程,select将监听的文件描述符再次拷贝到用户空间,然后select遍历这些文件描述符找到可用的IO文件,下次监控的时候需要再次拷贝这些文件描述符到内核空间,select支持监听的最大文件描述符为1024

(5.2) select 优缺点:
  • 优点:select目前几乎在所有的平台上支持,其良好的跨平台支持。
  • 缺点:
    • 每次调用select,都需要把监听的文件描述符从用户态拷贝至内核态,这个开销在文件描述符很多时会很大
    • 单个进程能够监视的文件描述符存的数量表在最大限制

(6) poll

(6.1) poll 运行原理

poll的机制和select类似,但是poll没有最大文件描述符数量的限制,poll使用链表保存文件描述符

(6.2) poll 优缺点
  • 优点:poll在应付大数目的文件描述符的时候相比select速度更快,它没有最大连接数限制,可以突破1024监听上限
  • 缺点:
    • 大量的文件描述符数组被整体复制于用户态和内核地址空间之间,
    • 与select一致,poll返回后,需要轮询pollfd来获取就绪的描述符

(7) epoll

(7.1) epoll 运行原理

epoll将这些文件描述符拷贝到内核空间后使用红黑树进行维护,同时向内核注册每个文件描述符的回调函数,当某个文件描述符可读可写的时候,将这个文件描述符加入到就绪链表中,并唤起进程,返回就绪列表到用户空间。

(7.2) epoll 优缺点
  • 优点:
    • 监视的描述符数量不受限制,它所支持的FD上限是最大可以打开的文件的数目,这个数字一般远大于1024
    • I/O的效率不会随着监视fd的数量增长而下降
  • 缺点:不能跨平台
(7.3) ET和LT
  • ET: ET是边缘触发模式,在这种模式下,只有当描述符从未就绪状态变成就绪状态是,内核才会通知epoll进行通知,然后直到下一次变成就绪之前,不会再次重复通知。优点是:只会通知一次,减少内核资源浪费,效率高。
  • LT:LT是水平触发模式,在这个模式下,如果文件描述符I/O就绪,内核就会进行通知,如果不对他进行I/O操作,只要还有未操作的数据,内核都会一直进行通知,有点事可以确保数据完整输出,缺点就是由于内核空间会一纸通知,会不停从内核空间切换到用户空间,资源浪费严重
(7.4) epoll读到一半又有新事件来了怎么办

避免在主进程epoll再次监听到同一个可读事件,可以把对应的描述符设置为EPOLL_ONESHOT,效果是监听到一次事件后就将对应的描述符从监听集合中移除,也就不会在被追踪到了。读完之后可以再把对应的描述符重新手动加上。

你可能感兴趣的:(#,C++面试题记录)