手机版

PHP多任务秒定时器的实现方法

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

形容

最近在公司部署crontab的时候,突然想到一个计时器是否可以用PHP实现,颗粒度和二级一样好,因为crontab高达分钟级。同时调查发现,在PHP中实现的定时器并不多。在Swoole扩展中实现毫秒级定时器非常高效,但毕竟不是用纯PHP代码写的,所以最后考虑在PHP中实现一个定时器类,供学习参考。

实现

在实现定时器代码时,使用了PHP系统的两个扩展

pcntl-多处理扩展:

主要是PHP可以同时打开很多子流程,并行处理一些任务。

spl-SplMinHeap-小顶部堆

一个小的顶堆数据结构,当定时器实现的时候,这种结构的效率还是不错的。插入和删除的时间复杂度为O(logN)。像libevent这样的计时器在1.4版之后采用这种数据结构之前也使用rbtree。如果使用链表或固定数组,每次插入和删除都可能需要重新遍历或排序,这仍然存在一定的性能问题。

过程

解释

1.定义定时器结构,有哪些参数等。2.然后把它们都注册到我们的定时器类Timer.3 .调用定时器类的monitor方法,开始监控。4.监控过程是一个一会儿没完没了的循环,不断检查时间堆的顶部是否到期。本来考虑每秒检查一次,后来还是每秒检查一次的问题。如果定时器刚好在我们睡觉的时候到期(1),那么我们就不能立刻准确地执行它,可能会有延迟的风险。因此,我们应该使用usleep(1000)毫秒来观察它并暂停进程,以减少CPU负载。

密码

/* * * *受保护的函数比较($value1,$ value 2){ if($ value 1[' time out ']$ value 2[' time out ']){ return-1;} if($ value 1[' time out ']$ value 2[' time out ']){ return 1;}返回0;}/* * * parent : insert($ value);}/* * *听* @ param bool $ debug */public function monitor($ debug=false){ while(!$ this-isEmpty()){ $ this-exec($ debug);us LEEP(1000);} }/* * * execute * @ param $ debug */private function exec($ debug){ $ hit=0;$t1=微时间(真);while(!$ this-isEmpty()){ $ node=$ this-top();If ($node['timeout']=time()) {//出堆还是入堆$node['repeat']?$ this-insert($ this-extract()): $ this-extract();$ hit=1;//打开子进程if(pcntl _ fork()==0){ empty($ node[' action '])?' : call _ user _ func($ node[' action ']);退出(0);}//忽略子进程,子进程退出系统恢复的pcntl _ sign(SIGCLD,SIG _ IGN);} else { break} } $t2=微时间(真);echo ($debug $hit)?时间堆调整需要:分钟。round($t2-$t1,3)。”秒\ r \ n“:”;}}实例

$ Timer=new Timer();//register-3s-repeat trigger $ timer-insert(array(' expire '=3,' repeat'=true,' action'=function () {echo' 3秒-repeat-hello world '。\ r \ n ';}));//register-3s-重复触发$ timer-insert (array ('expire'=3,' repeat'=true,' action'=function () {echo' 3秒-repeat-gogo '。\ r \ n ';}));//register-6s-trigger once $ timer-insert(array(' expire '=6,' repeat'=false,' action'=function () {echo' 6秒-once-hello xxxx '。\ r \ n ';}));//收听$ timer-monitor(false);执行结果

我也测试过极端情况,同时1000个定时器都在1s内到期,调整时间堆只需要0.126s。但是,需要在调整每个计时器后启动一个子进程,这可能很耗时。如果1000个定时器无法在1s内处理完,会影响下一次监控继续触发,但仍可以在不启动子进程的情况下进行处理,比如直接执行。当然肯定有更好的办法,到目前为止我也只能想到。

摘要

以上就是边肖介绍的PHP多任务秒定时器的实现方法。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你的!

版权声明:PHP多任务秒定时器的实现方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。