主要原理是通过PHP创建多个子进程,在子进程中发送进程闹钟信号,然后再监听闹钟信号中继续发送闹钟信号。同时通过父进程设置非阻塞运行。代码如下:
<?php /** * 订单任务 */ class Order { public function run() { file_put_contents("log1.txt", '我是订单任务,本次运行时间:' . date('Y-m-d H:i:s') . "\r\n", FILE_APPEND); } } /** * 商品任务 */ class Goods { public function run() { file_put_contents("log2.txt", '我是商品任务,本次运行时间:' . date('Y-m-d H:i:s') . "\r\n", FILE_APPEND); } } /** * Task任务核心 */ class Console { /** * 定时任务配置和执行时间间隔 */ protected static $tasks = [ 'Order' => 5, 'Goods' => 10, ]; /** * 初始化为每个任务分配进程 */ public static function init() { $tasks = self::$tasks; foreach ($tasks as $task => $second) { //创建子进程 $pid = pcntl_fork(); if ($pid == -1) { die ('创建子进程失败!'); } elseif ($pid) { //等待子进程执行完成回收,并且设置非阻塞 pcntl_wait($status, WNOHANG); } else { self::process($task, $second); //子进程执行完成关闭,避免重复fork die(); } } } /** * 子进程闹钟处理任务 */ public static function process($task, $second) { //安装信号管理 pcntl_signal(SIGALRM, function () use ($task, $second) { pcntl_alarm($second); $taskObj = new $task(); call_user_func([$taskObj, 'run']); }, false); //发送闹钟信号 pcntl_alarm($second); //调用等待信号的处理器 while (true) { pcntl_signal_dispatch(); } } } //初始化 Console::init();
程序执行后.主进程会根据已经配置的任务数来分配子进程,每个子进程来定时执行对应的任务,可以用来做redis消费者。
以上只是给你一个思路来实现,你还可以直接用我开源的定时器直接使用,访问地址:https://gitee.com/392223903/EasyTask
function objtoarr($obj){ $ret = array(); foreach($obj as $key =>$value){ if(gettype($value) == 'arr...
【一】.抽象类假设如下场景:团队准备开发某网站,表建好了,页面设计好了.A组负责开发底层数据库操作类(DB),B组负责调用DB类.但是此时A组发生了争执,MySQL? Oracle? DB2? sqlite?到底使用什么数据库?B组.... 进入漫长的等待.解决方法:A组和B组 先定1个数据库类的模...
PHP不像net支持多继承,自身只支持单继承,为了解决这个问题,php出了Trait这个特性,减少单继承语言的限制。并且能让代码复用率更高。说白了就是一个对象的属性和方法扩展工具一样。例如:trait exts { public f...
php arrayaccess 官方的说法是让你能以数组的形式访问对象,对于这种php内置接口一直不太明白有什么用,坚持多看文章,终于理解,特来分享,思路不同,更易于理解。(1).创建一个学生类,并且实现arrayaccess 接口。<?php class studen...
(1).前端文件:<form action="upload.php" method="post" enctype="multipart/form-data"> &...
(1).在PHP中可以查看的环境变量包括: (1.1).电脑环境变量 (2.1).服务器环境变量(2).getenv()函数获取一个环境变量的值.参数1是环境变量的key,参数2值为true的时候仅从你的电脑环境变量中查找,参数2值为false会从两种变量中全部查询//获取我电脑登录的用户名,输出A...