1 技术知识点
- 使用到
pcntl
包,主要使用到3个函数pcntl_fork
、pcntl_wait
、cli_set_process_title
- 确定好父子进程各自需要的变量,互不修改,但可查询。
- 父进程不参与业务,只负责创建task。
- 父进程退出时应当等待所有子进程退出(避免孤儿进程的产生)。
- 子进程只处理当前轮次的业务,不进入下一轮。
2 多进程基类
<?php
abstract class MultiWork
{
/**
* 进程标号:-1主进程
* @var int
*/
protected $sonId = -1;
/**
* work进程数量
* @var int
*/
protected $maxSon = 3;
/**
* 运行模式:single; multi
* @var string
*/
protected $mode = "single";
/**
* 运行的星期限制、24小时限制;多区间
* @var int[][]
*/
protected $workDay = [[0,6]];
protected $workTime = [[0, 23]];
/**
* 各work进程pid => logSign 注册表
* @var array
*/
protected $logMap = [];
/**
* 是否生成日志文件
* @var bool
*/
protected $log = false;
/**
* 日志内容分割符号
* @var string
*/
protected $logSta = " | ";
protected $logPath = ".";
protected $logFile = "work.log";
/**
* 数据库配置
* @var array
*/
protected $dbConf = [
'type' => 'mysql',
'host' => '127.0.0.1',
'port' => '3306',
'username' => '',
'password' => '',
'dbname' => 'test'
];
/**
* 实现业务逻辑处理
* @param $data "结构取决于getDataIterator"
* @return mixed
*/
abstract public function doBusiness($data);
/**
* 单进程时控制业务循环次数;多进程时控制总进程数量
* @return mixed
*/
abstract public function getDataIterator();
/**
* MultiWork constructor.
* @param array $config
* maxSon、mode、workDay、workTime、log、logSta、logPath、logFile
*/
public function __construct($config = [])
{
foreach ($config as $k => $v) {
!is_null($this->$k) && $this->$k = $v;
}
}
/**
* 启动方法
* <p>0.支持单/多进程切换</p>
* <p>1.启动条件限制:默认启动时其它同名进程需为0;其它逻辑请实现checkProcess</p>
* <p>2.子进程数量控制</p>
* <p>3.工作时间区间、工作日区间限制:控制脚本运行时间(不可运行时,最后的work完毕才退出)</p>
* <p>4.自动分配子进程日志:避免过程日志错乱</p>
*/
public function run()
{
!$this->checkProcess() && exit();
$canDo = true;
foreach ($this->getDataIterator() as $data) {
if (!($canDo = $this->canDo(