ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

php并发多进程任务

2021-01-22 10:31:14  阅读:200  来源: 互联网

标签:info logWirte needNumber private 并发 进程 pids php sqlObj


<?php
/*
* 业务需求 php开启5个子进程同步主表与从表数据
* 函数 pcntl_fork() 创建子进程  pcntl_wait回收子进程 
*/

include_once "./sql/Medoo.php";

use Medoo\Medoo;  //medoo框架 轻量级的PHP数据库框架, 提高开发效率

class Master
{
    private $forkNums = 5; //并发数
    private $pids = array(); //子进程临时存储
    private $limit = 0;
    private $offset = 100;
    private $time = 2; //并发任务间隔时间
    private $masterTableName = 'master'; //主表
    private $prepareTableName = 'spare'; //从表

    private function getSqlObj($type = 'M')
    {
        try {
            $masterClientData = include '../config/masterDb.php'; //主表配置
            $prepareClientData = include '../config/prepareDb.php'; //从表配置
            $configData = $type == 'M' ? $masterClientData : $prepareClientData;
            return new Medoo($configData);
        } catch (Exception $e) {
            $this->logWirte('error', $e->getMessage());
            exit;
        }
    }

    private function logWirte($type, $msg)
    {
        date_default_timezone_set('PRC');
        $fileName = $type == 'info' ? '../logs/info.log' : '../logs/error.log';
        $time = 'startTime:' . date('Y-m-d H:i:s') . " ";
        return file_put_contents($fileName, $time . $msg . PHP_EOL, FILE_APPEND);
    }

    public function sendTask()
    {
        try {
            $sqlObj = $this->getSqlObj('M');
            $total = $sqlObj->count("student_master", "*");
            $needNumber = ceil($total / $this->offset); //需要进程数
            $this->logWirte('info', "=======开始任务======本次需要执行任务数: " . $needNumber);
            while ($needNumber) {
                $this->logWirte('info', "=======开始任务======: " . $needNumber);
                $actualNumber = $needNumber < $this->forkNums ? $needNumber : $this->forkNums;
                $this->logWirte('info', "=======并发任务数======: " . $actualNumber);
                for ($i = 0; $i < $actualNumber; ++$i) {
                    $this->pids[$i] = pcntl_fork();
                    if ($this->pids[$i] == -1) {
                        die('fork error');
                    } else if ($this->pids[$i]) {
                        $this->limit += $this->offset;
                        $needNumber--;
                        pcntl_wait($status, WNOHANG);
                    } else {
                        $sqlObj = $this->getSqlObj('M');
                        $returndata = $sqlObj->select($this->masterTableName, "*", ['LIMIT' => [$this->limit, $this->offset]]);

                        $prepareMysqlObj = $this->getSqlObj('P');
                        $prepareMysqlObj->insert($this->prepareTableName, $returndata);

                        echo "父进程ID: ", posix_getppid(), " 进程ID : ", posix_getpid(), " {$i} \r\n";
                        $this->logWirte('info', "父进程ID: " . posix_getppid() . " 子进程ID : " . posix_getpid());
                        exit;
                    }
                }
                sleep($this->time);
            }
        } catch (Exception $e) {
            $this->logWirte('error', $e->getMessage());
            exit;
        }
    }
}

$obj = new Master();
$obj->sendTask();

参考文章 https://www.cnblogs.com/jkko123/p/6294602.html

标签:info,logWirte,needNumber,private,并发,进程,pids,php,sqlObj
来源: https://blog.csdn.net/qq_41862168/article/details/112978514

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有