PHP关于多进程用法的记录

        在工作中接触到了php多进程一段时间,在此做个记录,欢迎大家一起讨论学习。

        在项目中会涉及到很很多定时任务,这些定时任务会去完成数据处理,通常大量的数据会采用多进程来处理,这篇文章简单记录一下项目中用到的多进程。

       下面代码是多进程的定时任务

public function actionStartTest()
{

    $this->process_num = $this->process_num > 0 ? $this->process_num : 1;

    for ($current = 0; $current < $this->process_num; $current++) {

        $command = sprintf(PHP_EXEC . ' ' . YII_PATH . ' test/show-test --key=%s --    process_num=%s --current=%s --limit=%s > /dev/null &', $this->key, $this->process_num,             $current, $this->limit);

        echo $command . "\n";

        exec($command);

        usleep(100000);
    }
}

 

/**
 * 进行多进程调用
 */
public function actionShowTest()
{

    set_time_limit(0);

    error_reporting(0);

    $this->setMemoryLimit(1024);

    echo 'lock-key:'.'test-'.$this->key;

    //加锁
    $this->lock('test-'.$this->key);

    $ret = TestModel::getInstance()->dealData();

    //放锁
    $this->unlock();
    Clog::info('测试展示多进程-' . count($ret));
}

在执行定时任务的加锁代码:

/**
 * 进程锁
 * @param $processName
 */
public function lock($processName){

    if($this->process_num < $this->current){
        CommonLog::info(['msg' => '非法进程','processName' => $processName , 'processNum' => $this->process_num , 'current' => $this->current]);

    exit(0);
    }

    $this->_startTime = microtime(true);

    $this->_processName = "{$processName}-{$this->current}-{$this->process_num}-{$this->region}";

    $this->_lock = CommonModel::lock($this->_processName);

    if(!$this->_lock){
        CommonLog::info(['msg' => '抢占文件锁失败,已有相同进程运行','processName' => $this->_processName]);

    exit(0);
    }
}
/**
 * 获取锁
 * @param $fileName
 * @return bool|resource
 */
public static function lock($fileName)
{

    $lockFile = sys_get_temp_dir() . '/' . $fileName;

    $fp = fopen($lockFile, 'a+');

    if (flock($fp, LOCK_EX | LOCK_NB)) {

        return $fp;
    } else {

        return false;
    }
}

下面的代码是解锁代码:

public function unlock(){
    CommonModel::unlock($this->_lock);
    CommonLog::info(['msg' => '进程结束-执行时间为'.(microtime(true) - $this->_startTime),'processName' => $this->_processName]);
}
/**
 * 解锁
 * @param resource $fp
 */
public static function unlock($fp)
{

    $fp && flock($fp, LOCK_UN);
}

处理数据时候的代码,dealData方法中,获取数据会涉及到多进程

$startDate = date('Y-m-d H:i:s', time() - 86400 * 2);
if (\Yii::$app->params['process_num'] > 1) {

    $TestList = TestDao::find()
        ->select(['a.doc_id', 'b.id')
        ->where(['>', 'a.create_time', $startDate])
        ->andWhere('a.status = 0 AND b.error_count < 3 and a.id mod :processNum = :current', ['processNum' => \Yii::$app->params['process_num'], 'current' => \Yii::$app->params['current']])
        ->limit(\Yii::$app->params['limit'])
        ->asArray()
        ->all();
} else {

    //按照单线程处理即可
}

最后我们只需要加入定时任务即可:

* * * * * /usr/bin/php /home/service/app/test/release/information/yiiinformation test/start-test --key=xxx --process_num=43 --limit=1800

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值