linux处理高并发的事件模型-epoll

linux的事件模型-epoll

  • epoll事件模型是为了解决什么问题
  • epoll模型和select模型的区别
  • epoll的水平触发和边缘触发的区别
  • 如何创建一个epoll事件模型

对于传统的网络高并发请求情况下,通常是每一个请求会创建一个线程专门的处理该请求。所以当多个请求同时到达或同时需要处理,则会创建相同的多个线程去处理这些请求。而对于创建线程则需要占用大量的CPU开销。
例如:如果一台服务器是4核心的CPU,则在同一个时间点可以同时并行的处理4个请求。当CPU处理完这些请求后需要销毁这些线程并回收该资源,这个过程也会占用大量的CPU开销。
当线程较少的时候并不会出现性能瓶颈,但是当成千上万的请求同时访问时则会创建大量的线程。并且由于创建了大量的线程,所以导致各个线程相互争夺CPU资源导致CPU频繁的进行上下文切换。进而导致CPU无法很好的命中CPU的高速缓存。种种原因将会导致CPU无法用在处理用户真正的逻辑,而是频繁的处理线程的创建、销毁、协调以及上下文的切换上。

epoll事件模型是为了解决什么问题

epoll是为了解决当并发高时需要创建多线程对同时到来的请求进行处理的问题。epoll事件模型通过基于事件触发的形式将多线程同步处理请求的问题转换为单进程异步处理请求

为了能让单进程处理多个请求,所以在整个程序运作过程不能出现阻塞现象(或者说不能出现频繁的阻塞现象)。所以对于每个请求需要被设定为非阻塞的方式。进而需要通过事件回调来处理事件触发后的情况。
举个例子:

  • 假如有一家饭店:
    • 把客人比作“请求”
      • 客人吃饭视为“真正要处理的内容”
      • 客人不吃饭干坐着视为“阻塞等待,啥也不干”
    • 把服务员比作“进程(线程)”
    • 把经营饭店的开销比作“CPU的处理能力”。
  • 对于同步多线程可以比作是:
    • 每一个客人都会有一个服务员对该客人进行专门服务;不管这个客人是否点餐都会耗费服务员的时间(也就意味着都需要付给服务员工资),这种方式固然服务好但是却费钱(耗费CPU资源)
  • 对于异步单进程(少量进程/线程)可以比作是:
    • 每当有一个客人来的时候只会将菜单给客人(建立连接后就不管这个请求了),之后服务员就会去忙其他的事情(例如给另一个客人递菜单)。当一个客人点完餐后只要吆喝一嗓子“说点完菜了”(触发事件回调)。服务员就过来将客人需要的菜端上来给客人(需要处理的请求)。这种方式虽然服务没有上面的好,但是明显效率更高也更省钱。因为只需要请几个能力强的“服务员”就能处理很多的“客人”。

对于epoll的事件模型,就可以比作上面的异步单进程例子。

epoll模型和select模型的区别

epoll模型和select模型主要的不同在于“如何知道客人已经点完菜了”。

  • 对于epoll模型:是告诉客人如果点完菜了就喊一声。然后服务员就上去给客人上菜。
  • 对于select模型:是不需要让客人喊服务员说点完菜了,而是让服务员不断的循环的去一个一个的询问每个客人是否点完菜了。点完了就上菜没点完就询问下一个客人。

当客人比较少的时候,上面这两种方式效率都很高,因为轮询一次的时间较少。但是当客人很多并且很多客人都处于点餐状态而不是上菜状态则epoll模型会有很大的效率优势。而如果对于大多数客人都是处于上菜状态则两者的效率也差不多。

但是在日常的开发中,其实很多连接都是处于类似于点餐的状态。所以就会导致epoll的效率远远高于select。

总结:对于高并发连接但不是每个连接都是高活跃的使用epoll的效率会远远高于select。而对于如果每个连接都是高活跃的,则epoll的效率和select的效率差不多。

epoll的水平触发和边缘触发的区别

对于epoll模型的水平触发和边缘触发的区别在于类似于上菜的过程:
水平模式:假设一次炒好了3盘菜并喊服务员来端菜,第一次上了1盘菜,还有2盘菜没有上。只要厨房还有已经为客人炒好的菜,就会不断的来往厨房将所有的菜上完为止。
边缘模式:假设一次炒好了3盘菜并喊服务员来端菜,第一次上了1盘菜,还有2盘菜没有上。服务员并不会和水平模式一样往返于厨房和客人之间直到把菜上齐,而是等待下次厨房说客人其他的菜也炒好了才会再去厨房把菜送给客人。所以对于边缘触发需要一次性将3盘菜全部端给客人这样才不会遗漏已经炒好的菜。

水平触发和边缘触发的优缺点:

  • 水平触发的优点:

    • 设计较为简单,因为对于一个事件的信息没有读取完就会一直通知到读取完为止。
  • 水平触发的缺点:

    • 性能较低,如果没有取完数据就会不断的通知,从而导致性能降低。
  • 边缘触发的优点:

    • 当事件被触发时只会通知一次,性能高。
  • 边缘触发的缺点:

    • 由于事件触发时只会通知一次,所以一定要对处理完这一次触发事件,不然不会再通知。需要更高的编程能力,容错率低。

如何创建一个epoll事件模型

你可能感兴趣的:(linux的函数)