当前位置: 首页 > 后端技术 > PHP

PHPSocket初探---颤抖开启Libevent(一)

时间:2023-03-30 01:17:38 PHP

【原文地址:https://blog.ti-node.com/blog...】如题所示,颤抖开启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)个快递,阿妹都会冲你吼一句:“顺丰镖局大哥的铁头套,圆通镖局六师弟的彩蛋到了!”,而且不用你依次翻单,阿妹会直接告诉你哪个镖局在押送哪个快递员,然后她就会按照你说的去做”她提前“收到蛋就给六师弟,收到铁头甲就给师兄。就算你买了一万个快递,阿妹也会用太极功夫来收快递,而你只需要静静修炼强大的金刚腿即可。剃了光头的阿梅是个挑剔的,不敢正眼看老板娘。剃了光头的阿梅是epoll,可以徒手接住恶魔的死球。expressdelivery相当于socketfd,包括监听socket和连接socket;该列表是fds的集合;阿妹是select还是epoll;你是当前进程;当某一个快递到了,就相当于某个fd已经被读取或者可以写入了。select虽然在一定程度上解决了一个进程可以读写多个fd的问题,但是select有以下致命缺陷:默认情况下select可以管理的fd数量是1024个(阿妹最多可以帮你收1024个快递)每次select检测到fd集合中有可读可写的fd,就会把整个fd复制给你,然后你再一个一个轮询哪个fd是可读可写的。上面说了,它会把整个fdCopy给你(她copy了整个list给你)。这个过程用术语来说就是将fd从内核态拷贝到用户态的调用进程。上面说了,你自己一个一个轮询所有的fds都可以知道哪个是可读可写的(反正有快递来了,有多少,你自己查表)你自己的轮询过程是线性的,如果有nfd,那么时间复杂度一定是O(n)并且epoll有更专业的高端高端技能指标:理论上可以处理无限的fd(可以收无数快递的阿妹),只挑出可读的写(其实严格意义上也有例外)activefd,剩下的fd会被忽略。使用MMAP加速内核模式数据复制。另外需要指出的是,epoll本身有两种模式:水平触发。这样,如果检测到X个事件,内核态就会把这些事件复制到用户态,但不幸的是,如果用户只处理了其中一个,剩下的X-1个事件由于某些原因被忽略了,所以下一次,这些未处理的X-1事件仍会从内核态复制到用户态。这样做既有积极的一面,也有消极的一面。积极的一面是事件是安全的,不会丢失,消极的一面是浪费性能。其实这时候的epoll和poll的工作方式很相似。边缘触发。这样一来,就是epoll的鸡血版,释放自己的是epoll,应该才是正确的使用方式。在这种情况下,如果发生了X个事件,但您只处理了其中的1个,则剩余的X-1个事件被视为“丢失”。性能正在上升,并且可能会丢失事件。所以,你以为是时候写代码演示epoll了,但是没有,原因有二:epoll可以直接通过C语言来操作,但是,为了避免假装失败,我决定不使用C来演示(放在后面再深入的时候)如果说是通过PHP来操作,不得不提一个悲催的。根据我自己的经验,告诉我PHP不能直接控制epoll,必须通过操作libevent来处理epoll。那么,什么是Libevent?为什么听起来很耳熟,不仅是耳熟,看看下图,是不是很耳熟?没错,本博客的前端页面是从Libevent官网复制过来的。我先从Libevent官网复制了一段话:“目前libevent支持/dev/poll,kqueue(2),eventports,POSIXselect(2),Windowsselect(),poll(2),andepoll(4)。“,你大概可以知道Libevent是干什么的。大致意思就是Libevent封装了Mac中的/dev/poll、kqueue、select、poll、epoll的API,屏蔽了这些多路复用开发中的一些细节和差异,对外提供了一个统一的API,一个高性能的网络事件库。额外提醒一下,这个东西是用C语言写的,几十年过去了,你大爷还是你大爷。回到正轨,就是《如何在PHP中使用Libevent》。在pecl.php.net上,有两个扩展可以让phper方便的控制libevent。一个叫做libevent,另一个叫做event。我们建议您使用后者。不知什么原因,之前的版本一直停留在0.10Beta状态,开发日期停留在2013-05-22。没怎么试过,可能不支持php7,不过还是要感谢开发者。事件扩展比较牛逼,版本迭代不错,看来开发者很活跃,而且还支持php7,目前稳定版是2.3.0,所以推荐大家使用事件扩展。这里只是添加php扩展的安装方法,以事件扩展为例。下载event2.3.0稳定版,wgethttps://pecl.php.net/get/even...解压tgz源码包,tar-zxvfevent-2.3.0.tgzcdevent-2.3.0进入main目录,然后执行phpize,然后执行./configure,执行make,执行makeinstall,安装配置php的cli环境配置文件,注意不是apache2,也不是fpm,而是cli的php.ini,添加一个一句:extension='/usr/lib/php/20151012/event.so',然后在终端执行php-m,看看有没有事件?好了,今天正式到这里结束,下一篇继续讲php和他的事件扩展!【原文地址:https://blog.ti-node.com/blog...】