菜鸟笔记
提升您的技术认知

水平触发和边缘触发-ag真人游戏

1.水平触发(lt)

当被监控的文件描述符上有可读写事件发生时,会通知用户程序去读写,他会一直通知用户,如果这个描述符是用户不关心的,它每次都返回通知用户,则会导致用户对于关心的描述符的处理效率降低。

复用型io中的select和poll都是使用的水平触发模式。

2.边缘触发(et)

当被监控的文件描述符上有可读写事件发生时,会通知用户程序去读写,它只会通知用户进程一次,这需要用户一次把内容读取完,相当于水平触发,效率更高。如果用户一次没有读完数据,再次请求时,不会立即返回,需要等待下一次的新的数据到来时才会返回,这次返回的内容包括上次未取完的数据

epoll既支持水平触发也支持边缘触发,默认是水平触发。

3.比较

水平触发是状态达到后,可以多次取数据。这种模式下要注意多次读写的情况下,效率和资源利用率情况。

边缘触发数状态改变一次,取一次数据。这种模式下读写数据要注意一次是否能读写完成。

4.et模式带来的问题

  1. 因为只有当缓冲区中数据由无到有,由少变多时才会区读取数据,
    所以一次要将缓冲区中的数据读完,否则剩下的数据可能就读不到了。
    正常的读取数据时,我们若是要保证一次把缓冲区的数据读完,意为本次读被阻塞时即缓冲区中没有数据了,可是我们 epoll 服务器要处理多个用户的请求,read()不能被阻塞,所以采用非阻塞轮询的方式读取数据。

  2. 若轮询的将数据读完,对方给我们发9.5k的数据,我们采取每次读取1k的方式进行轮询读取,在读完9k的时候,下一次我们读到的数据为0.5k,我们就知道缓冲区中数据已经读完了就停止本次轮询。
    但还有一种情况,对方给我们发的数据为10k,我们采取每次读取1k的方式轮询的读取数据,当我们已经读取了10k的时候,并不知道有没有数据了,我们仍旧还要尝试读取数据,这时read()就被阻塞了。

5.epoll应用场景

(1) 适合用epoll的应用场景:对于连接特别多,活跃的连接特别少,这种情况等的时间特别久,典型的应用场景为一个需要处理上万的连接服务器,例如各种app的入口服务器,例如qq

(2)不适合epoll的场景:连接比较少,数据量比较大,例如ssh

epoll 的惊群问题:因为epoll 多用于 多个连接,只有少数活跃的场景,但是万一某一时刻,epoll 等的上千个文件描述符都就绪了,这时候epoll 要进行大量的i/o,此时压力太大。

网站地图