主要原理是通过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
在PHP中,大部分变量类型,如字符串,整型,浮点,数组等都是值类型的,而类和对象是引用类型.和其他语言有点差距.(1).在值类型中我们直接使用&符号表示指向对应变量的内存地址,当前变量和被指向的变量只要有1个的值被修改都会直接影响另外一个变量的值发生变化。(ps:还是非常节省内存的,可以使用...
在一个正式项目中操作人员提交239个产品信息进行保存,但是系统却提示没有提交239个产品,于是开启错误信息,显示如下:Warning: Unknown: Input variables exceeded 1000. To incr...
开发com组件可以用c++,vc++,net,我比较熟悉net,演示用dnet(1).创建项目:启动vs2017,新建项目,选择Visual C# ->Windows桌面->类库通用windows(2). 修改Com项目:点击 项目->项目属性,再点击应用程序->程序集信息,...
array_merge是最常用的数组合并方法,+号同样也可以,但是却有很大不同。array_merge遇到相同字符串key,后面数组的key会覆盖前面数组的key,+号正好相反。$a = [ 'one' => 'A on...
<?php /** * @throws Exception */ function curl() { throw new \Exception('err...
自己的composer已经发布到packagist,但是无法使用composer require easy-task/easy-task来安装,只能在配置文件使用如下方式安装:"require": { "easy...