php pcntl_fork 多进程

 php,pcntl_fork,多进程处理数据,这里需要注意的是,如果是处理数据库数据,并发量会将数据库的资源占满,要注意数据资源的分配

<?php

namespace App\Console\Commands\WorkCustomer;

use TaskDetail;

class TaskMore extends Command
{
    /**
     * 每个进程处理的条数
     */
    public $maxDataCount;

    /**
     * 最大的子进程数量
     */
    public $maxChildPro = 50;

    /**
     * 当前的子进程数量
     */
    public $curChildPro = 0;

    //当子进程退出时,会触发该函数,当前子进程数-1
    public function sig_handler($sig)
    {
        global $curChildPro;
        switch ($sig) {
            case SIGCHLD:
                echo 'SIGCHLD', PHP_EOL;
                $curChildPro--;
                break;
        }
    }

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'task_more';

    /**
     * 说明
     * The console command description.
     *
     * @var string
     */
    protected $description = '任务-多进程';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        set_time_limit(0);
        try {
                $allTaskDetailCount = TaskDetail::query()->where([
                    'task_id' => $taskId
                ])->count(); // 当前任务,详情数量
                $this->maxDataCount = (int)ceil($allTaskDetailCount / $this->maxChildPro); // 总条数÷最大子进程,获取到每个进城最大处理的条数
                if ($this->maxDataCount == 0) {
                    throw new \Exception('未找到数据');
                }
                while ($this->curChildPro < $this->maxChildPro) {
                    $this->curChildPro++;
                    $pid = pcntl_fork();
                    if ($pid == -1) {
                        throw new \Exception('fork子进程失败!');
                    } else {
                        if ($pid) {
                            // 阻塞父进程,直到子进程结束,不适合需要长时间运行的脚本.可使用pcntl_wait($status, WNOHANG)实现非阻塞式
                            pcntl_wait($status, WNOHANG);
                        } else {
                            // 这里开始处理逻辑
                            $s = rand(2, 6);
                            sleep($s);
                            exit;
                        }
                    }
                }
            }
        } catch (\Exception $e) {
            Log::info('task_more:error' . $e->getMessage());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值