php pcntl_fork 多进程

2023-12-21 10:59:47

?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());
        }
    }
}

文章来源:https://blog.csdn.net/yang_yun_hao/article/details/135123617
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。