该类基于 socket 的select io复用,对Workerman框架接口EventInterface的实现。而select之前也有讲解过,之不过那时只提到select复用readio。
那么通过workerman框架,我们要学会其是如何完成定时任务
1、Select
1.1、类设计
- 类概要图
1.2、源码
- 实例化 Select类对象时,在其 构造方法 中,设置channel管道,并实例化SplPr io rityQueue对象,赋值给_scheduler
- 新event对象时,调用add方法,其内部实现逻辑,判断对象类型
- 没有当删除event对象时,调用del方法,其内部实现逻辑,如下
为EV_EXCEPT时,则在_allEvents和_exceptFds等数组进行查找,并删除
为EV_READ时,则在_allEvents和_readFds等数组进行查找,并删除
为EV_WRITE时,则在_allEvents和_writeFds等数组进行查找,并删除
为EV_TIMER或EV_TIMER_ONCE时,则在_eventTimer数组进行查找,并删除
为EV_SIGNAL时,则在_signalEvents数组进行查找,并删除,然后去掉信号安装
- loop
死循环检测
调用pcntl_signal_dispatch,进行子进程的信号分发
等待stream_select函数的返回
判断定时任务数组_scheduler是否为空,如不为空则调用tick方法,进行定时任务处理
从stream_select得到的结果,进行判断和遍历
- destroy
空实现
- getTimerCount
返回定时器的任务个数
- signalHandler
信号回调方法
- clearAllTimer
清空数组_eventTimer,并重置_scheduler对象
- tick
定时任务数组_scheduler是否为空,不为空则进行调用_scheduler的top方法,获得第一个任务信息
并把定时任务要执行的时间与当前时间进行操作,并赋值给_selectTimeout
对_selectTimeout进行判断,如满足则执行该定时任务
1.3、总结
通过阅读Select类源码,select函数
stream_select($read, $write, $except, $tv_sec, $tv_usec);
在网络io的复用场景,可以通过select的前三个参数$read, $write, $except进行获取
- 而$tv_sec, $tv_usec这两个参数的存在意义是什么
答: 这两个参数都是时间单位的参数,其中$tv_sec为秒,而$tv_usec为微秒。但在调用stream_select方法时,两者都为0,则不阻塞,立即返回。相反如存在任意一个,则进行阻塞对应的时间,才返回。因此,在workerman框架,就是利用了个阻塞的时间,配合SplPriorityQueue,进行定时任务。这也是在调用add方法或tick方法时,需要操作属性_selectTimeout的原因
- 如何实现信号通信?
答,在loop方法中,调用pcntl_signal_dispatch进行信号分发
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~