zoukankan      html  css  js  c++  java
  • select和epoll最大的区别

    先说说阻塞,因为一个线程只能处理一个套接字的I/O事件,如果想同时处理多个,可以利用非阻塞忙轮询的方式,伪代码如下: 

    复制代码
    while true  
    {  
        for i in stream[]  
        {  
            if i has data  
            read until unavailable  
        }  
    }  
    复制代码

    我们只要把所有流从头到尾查询一遍,就可以处理多个流了,但这样做很不好,因为如果所有的流都没有I/O事件,白白浪费CPU时间片。正如有一位科学家所说,计算机所有的问题都可以增加一个中间层来解决,同样,为了避免这里cpu的空转,我们不让这个线程亲自去检查流中是否有事件,而是引进了一个代理(一开始是select,后来是poll),这个代理很牛,它可以同时观察许多流的I/O事件,如果没有事件,代理就阻塞,线程就不会挨个挨个去轮询了,伪代码如下: 

     
    复制代码
    while true  
    {  
        select(streams[]) //这一步死在这里,知道有一个流有I/O事件时,才往下执行  
        for i in streams[]  
        {  
            if i has data  
            read until unavailable  
        }  
    }  
    复制代码

     但是依然有个问题,我们从select那里仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。

    epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))伪代码如下:

    复制代码
    while true  
    {  
        active_stream[] = epoll_wait(epollfd)  
        for i in active_stream[]  
        {  
            read or write till  
        }  
    }  
    复制代码

    可以看到,select和epoll最大的区别就是:select只是告诉你一定数目的流有事件了,至于哪个流有事件,还得你一个一个地去轮询,而epoll会把发生的事件告诉你,通过发生的事件,就自然而然定位到哪个流了。不能不说epoll跟select相比,是质的飞跃,我觉得这也是一种牺牲空间,换取时间的思想,毕竟现在硬件越来越便宜了。

  • 相关阅读:
    Oracle中模拟SQL中的isnull函数
    Delphi:在OnBeforePost事件中取消TDataSet.Post(Delphi: Canceling a TDataSet.Post in an OnBeforePost Event)
    DBGrid的输入焦点控制
    刷新dbgrid 而不失去当前行位置
    MoveTo和MoveBy
    接口及接口测试
    ()文献可视化--vosviewer入门
    给出先序和中序,给一个数找到位置并输出它左子树里最大的数
    Kruskal算法:最小生成树
    Prim算法:最小生成树
  • 原文地址:https://www.cnblogs.com/setevn/p/8779269.html
Copyright © 2011-2022 走看看