正如标题所言,颤颤抖抖开篇epoll。颤颤抖抖的原因大概也就是以前几乎没有亲自“手刃”epoll的经验,仅仅靠epoll的理论知识骗吃骗喝骗人事哄小孩儿装高手,现如今,没有了大师兄的铁头功照顾,没有了六师弟的轻功水上漂背,没有了阿梅的太极功护身,不得不自己个儿当一次排头兵了。

说到底,还是因为自己虚。

先立个flag,那就是epoll比select牛逼,尽管select是POSIX标准。即便是select的高配版本poll,也比epoll差太多太多。网络如此发达的今天,epoll是解决c10k问题的功臣,这是没有办法的事情。epoll虽然是后出生的,但是却有着与生俱来的高傲,就像王思聪;select就是普通屌丝,花点儿钱使劲装扮自己也顶多就是个poll。这poll和epoll,可差一个e呢,没办法,与生俱来的差距。

坊间传闻,在epoll出世前,QQ用户量剧增,但是select以及select的高配版本poll都无法解决他们的问题,于是乎QQ当年的服务器就不得不用UDP协议来避规这个问题,一直到后来有了epoll,QQ开始逐步在PC客户端中的配置项中允许用户选择UDP服务器或TCP服务器。

还是通过浅显的示例来说明下为啥epoll比select厉害(这个例子在前面文章中应该提过,今儿再回放一遍)。

你要去继续练习大力金刚腿,阿梅还是要替你收双十一的10个快递。为了方便自己记忆这些快递,你把十个快递记录到了一个清单上给了阿梅。但这个时候阿梅显然不太清楚怎么应付这场景,于是每当收到X个快递,阿梅都是直接把快递清单抄写一份再拿给你并告诉你:“有快递来了!”,至于来了几个快递以及是分别是哪个镖局护送的,阿梅是不会告诉你的。于是只能是你自己,把单子上的10个快递逐次和收到的对比一遍,然后对比完毕后再把这个单子给了阿梅,然后阿梅继续等。

又是一年双十一,阿梅这次学聪明了,经历过那场球赛后,她已经得到了自我,实现了人生价值,今年的阿梅是一个全新的阿梅,一个剃了光头的阿梅。

你要去继续练习大力金刚腿,阿梅还是要替你收双十一的10个快递。为了方便自己记忆这些快递,你把十个快递记录到了一个清单上给了阿梅。但这个时候的阿梅显然已经得到了自我,是升华了的阿梅,于是每收到X个( X >= 1 )快递,阿梅都会在冲你喊一句:“顺丰镖局大师兄的铁头套,圆通镖局六师弟的鸡蛋到了!”,而你,不用再去依次对单子,阿梅会直接告诉你是哪个镖局护送的哪个快递,然后她还会按照你提前告诉她的“如果收到鸡蛋就给六师弟,收到铁头套就给大师兄”。哪怕你买了10000个快递,阿梅照样四两拨千斤,太极功夫收快递,而你,只需要安静的练习大力金刚腿。

剃光头前的阿梅,就是select,不敢正眼看老板娘一眼。

剃光头后的阿梅,就是epoll,可徒手接魔鬼队的死亡之球。

快递就相当于是socket fd,包括监听socket和连接socket;那个清单就是fd的集合;阿梅就是select或者epoll;你就是当前的一个进程;某个快递到了,就相当于是某个fd已经可读或可写。

select虽然一定程度上解决了一个进程可以读写多个fd的问题,但是select有如下致命缺点:

默认情况下,select可管理的fd的数量是1024个(阿梅最多帮你收1024个快递)

select每次检测到fd集合中有可读写的fd时,它会把整个fd全部复制一遍给你,然后你自己再去逐个轮询究竟是哪个fd可读写

正如以上所说,它会把整个fd全部复制给你(她把整个清单抄了一份给你),从术语上讲,这个过程是将fd从内核态复制一遍给用户态的调用进程

正如以上所说,你自己逐个轮询所有fd才能知道究竟是哪个可读写(反正就是有快递来了,来了几个都是谁你自己个儿对着清单查去)

你自己个轮询的过程是线性的,如果有个n个fd,那么时间复杂度一定是O(n)

而epoll则拥有更加专业的高端大气上档次的技能指标:

理论上可以搞定无上限的fd(可以收无数个快递的阿梅)

只挑出可读写(其实严格意义上还有异常)的活跃的fd,其余的fd不理会

使用MMAP加速内核态数据拷贝

除此之外,需要特殊指出的是,epoll本身的两种模式:

水平触发。这种方式下,如果监听到了有X个事件发生,那么内核态会将这些事件拷贝到用户态,但是可惜的是,如果用户只处理了其中一件,剩余的X-1件出于某种原因并没有理会,那么下次的时候,这些未处理完的X-1个事件依然会从内核态拷贝到用户态。这样做是有阴阳两面的,阳面是事件安全的不会发生丢失,阴面是对于性能来说是一种浪费。其实这个时候的epoll颇有些类似于poll的工作方式。

边缘触发。这种方式下,是鸡血版本的epoll,是释放自我的epoll,也是应该是正确的使用方式。这种情况下,如果发生了X个事件,然而你只处理了其中1个事件,那么剩余的X-1个事件就算“丢失”了。性能是上去了,与之俱来的就是可能的事件丢失。

那么,你以为是时候写代码演示epoll了,然而并不是,原因有两个:

通过C语言可以直接操作epoll,但是,为了避免装逼失败,我决定不用C来演示(放到后面再深入的时候)

如果说通过PHP来操作,我不得不提一件悲催的事情,据我自己得到的经验告诉我 那就是PHP无法直接操控epoll,而是要通过操作libevent来搞定epoll。

那么,什么是Libevent呢?怎么听着好耳熟,不光耳熟,你看下下图,是不是还有点儿眼熟?没错,这的博客的前端页面就是抄的Libevent官网的。

我先从Libevent官网抄袭一段话:“Currently, libevent supports /dev/poll, kqueue(2), event ports, POSIX select(2), Windows select(), poll(2), and epoll(4). ”,你就能大概知道Libevent是干啥的了。大概意思就是Libevent对/dev/poll、Mac中的kqueue、select、poll以及epoll的API进行了封装,屏蔽了这几个多路复用开发上的一些细节和不同点,对外提供统一的API的一个高性能网络事件库。

额外提醒一点,这个东西是用C语言编写的,几十年过去了,你大爷还是你大爷。

回到正路上来,就是“PHP中如何使用Libevent”。在pecl.php.net上,有两个扩展都可以使phper方便地操控libevent,一个就叫libevent,另一个叫做event,推荐大家用后者。前者不知道什么原因版本一直停留在0.10 Beta状态,开发日期则停留在了2013-05-22日,我没怎么试过,估计可能不支持php7,不过,还是要感谢开发者。event扩展就比较屌了,版本迭代不错,看起来开发者挺积极的,也支持php7,目前的稳定版本是2.3.0,所以推荐大家使用event扩展。

正好在此补充一下php扩展的安装方式,以event扩展为例。

解压tgz源码包,tar -zxvf event-2.3.0.tgz

cd event-2.3.0进入到主目录中,然后执行phpize,再执行./configure

执行make

执行make install安装

配置php的cli环境配置文件,注意不是apache2,也不是fpm的,而是cli的php.ini,添加一句:extension = '/usr/lib/php/20151012/event.so',然后在终端中执行php -m看下,是不是有event呢?

好了,今天到这里正式收官,下一篇继续嗑php和他的event扩展二三事!

php实现epoll,PHP socket初探 --- 颤颤抖抖开篇libevent(一)相关推荐

  1. PHP socket初探 --- 一些零碎细节的拾漏补缺

    原文:https://t.ti-node.com/thread/... 前面可以说是弄了一系列的php socket和多进程的一大坨内容,知识浅显.代码粗暴.风格简陋,总的说来,还是差了一些细节.今天 ...

  2. epoll实现socket通信

    epoll是Linux特有的I/O复用函数,它在实现和使用上与select和poll有很大差异.epoll使用一组函数来完成任务,而不是单个函数.epoll把用户关心的文件描述符上的事件放在内核的一个 ...

  3. C++多线程编程以及epoll处理socket通信时多端口问题

    问题根源:当有许多客户端用socket来连接我的服务器(期间存在一定的数据交互)的时候,为了提高性能,我们需要采用多线程编程(处理具体的请求),同时还要使用epoll来高效的在IO事件之间切换(侦查s ...

  4. 使用epoll&socket的总结

    1. epoll 中使用et方式触发,只需EPOLL_CTL_ADD一次,把EPOLLIN  EPOLLOUT 事件全注册,每个socket只需创建add一次,其事件就会 一直在epoll中,当然,s ...

  5. php libevent 问题,PHP Socket 初探 —— 硬着头皮继续 libevent(二)

    libevent中有五个字母是event,实际上就是说"event才是王道". Event类就是产生各种不同类型事件的产出器,比如定时器事件.读写事件等等,为了提升民族荣誉感,我们 ...

  6. C# Socket初探

    闲着无聊,写了个简单的C/S Socket程序,功能很简单,服务器在9000端口监听socket接入,只要有接入,就发送"Welcome."消息给客户端. 代码分2块,server ...

  7. linux多网卡网络编程,Linux网络编程之Socket初探

    Socket由来 Socket 的英文原意就是"孔"或"插座",现在,作为 BSD UNIX 的进程通讯机制,取其后一种意义.一起看下网络编程里说的socket ...

  8. 填坑之PHP的yield和协程在一起的日子里

    首先是,这是我第一次把公众号文章复制粘贴到github来. 其次是,很久很久之前,我挖了一个yield的一个坑,自己挖的坑自己填,不然迟早会把自己埋掉. 最后是,如果想看之前那个坑,请发送" ...

  9. 狗咬吕洞宾,不识好人心的来历

    吕洞宾成仙得道之前,原是个读书人.他的好友中有个同乡叫苟杳.苟杳父母双亡,家境贫寒,但为人忠厚,是一个老诚君子,读书又很勤奋,吕洞宾很赏识他,与他结拜为金兰兄弟,并请他到自己家中居住,希望他能刻苦读书 ...

最新文章

  1. 注册界面翻译_B站UP主自制的开源OCR翻译器走红Github,用一次就粉了
  2. 股票投资--中线篇(转)
  3. 让LoadRunner再次走下神坛
  4. Navisworks Api Tool
  5. 如何查看某个employee被assign到了哪个sales organization上
  6. MySQL Cookbook 学习笔记-02
  7. 虹软安卓人脸识别初学
  8. 用Matlab分享一个软件低通滤波算法
  9. Java -- JSP面试题及答案
  10. 3dmax如何建模(二)
  11. UltraEdit如何激活
  12. 【C++】重定义,重载,重写
  13. android开发塔防游戏机,上手快又耐玩 五款Android平台塔防类游戏推荐
  14. 关于:昨天H - 康托展开题目的探究。
  15. 泛函分析笔记(十七) 弱偏导数
  16. Word文档怎么转PDF?这里有需要掌握的方法
  17. 图像处理------图像加噪
  18. slice()、substring()、substr()区别和用法
  19. 如何使用开源合成器Natron入门
  20. 自然几何之分形(2)

热门文章

  1. HTML+CSS基础知识5
  2. 我的世界服务器状态图片,我的世界服务器
  3. 7和7的倍数游戏答案_月流水一亿的传奇游戏“贪玩蓝月”遭遇危机,还能够延续辉煌吗?...
  4. 人为什么要努力?编程、学习之路…很迷茫?个人经验分享
  5. vs-OpenGL编程入门学习
  6. 风信子靶场题目SMC复现及解题思路
  7. Excel Power Pivot刷新后数据不更新
  8. 高铁乘务员搜题软件哪个好?工资一般多少?
  9. 一维数组——计算平均分
  10. stata实证之前通常处理步骤