php三种实现多线程类似的方法


Posted in PHP onOctober 30, 2015

1、curl_multi方法

当需要多线程的时候,可以用curl_multi一次性请求多个操作来完成,但curl走的是网络通信,效率与可靠性就比较差了的。

function main(){ 
 
   $sql = "select waybill_id,order_id from waybill where status>40 order by update_time desc limit 10 "; 
 
    $data = Yii::app()->db->createCommand($sql)->queryAll(); //yii 框架格式 
 
    foreach ($data as $k => $v) {  
 
      if ($k % 2 == 0) { //偶数发一个网址 
 
        $send_data[$k]['url'] = ''; 
 
        $send_data[$k]['body'] = $v['waybill_id']; 
 
      } else { //奇数发送另外一个网址 
        $send_data[$k]['url'] = 'http://www.abc.com'; 
 
        $send_data[$k]['body']=array($v['order_id'] => array('extra' => 16)); 
 
      } 
 
    } 

    $back_data =sendMulitRequest($send_data); 
 
    var_dump($back_data); 
 
  } 
  function sendMulitRequest($send_data){ 
    $params = array(); 
    $curl = $text = array(); 
    $handle = curl_multi_init(); 
 
    foreach ($data as $k => $v) { 
 
      if (empty($v['url'])) { 
 
        $v['url'] = "http://www.xxx.com"; //if url is empty,set defalut url 
 
      } 
 
      $reqBody = json_encode($v['body']); 
 
      $reqStream = array( 
 
        'body' => $reqBody, 
      );  
      $encRequest = base64_encode(json_encode($reqStream));  
      $params['data'] = $encRequest; 
      $curl[$k] = curl_init(); 
      curl_setopt($curl[$k], CURLOPT_URL, $v['url']); 
      curl_setopt($curl[$k], CURLOPT_POST, TRUE); 
      curl_setopt($curl[$k], CURLOPT_HEADER, 0); 
      curl_setopt($curl[$k], CURLOPT_POSTFIELDS, http_build_query($params)); 
      curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1); 
      curl_multi_add_handle($handle, $curl[$k]); 
    } 
    $active = null; 
 
    do { 
 
      $mrc = curl_multi_exec($handle, $active); 
 
    } while ($mrc == CURLM_CALL_MULTI_PERFORM); 
    while ($active && $mrc == CURLM_OK) { 
 
      if (curl_multi_select($handle) != -1) { 
 
        do { 
 
          $mrc = curl_multi_exec($handle, $active); 
 
        } while ($mrc == CURLM_CALL_MULTI_PERFORM); 
 
      } 
 
    } 
    foreach ($curl as $k => $v) {  
      if (curl_error($curl[$k]) == "") { 
        $text[$k] = (string) curl_multi_getcontent($curl[$k]); 
       }  
      curl_multi_remove_handle($handle, $curl[$k]);  
      curl_close($curl[$k]); 
    } 
    curl_multi_close($handle);  
    return $text;  
  }

2、通过stream_socket_client 方式

function sendStream() { 
    $english_format_number = number_format($number, 4, '.', ''); 
 
    echo $english_format_number;  
    exit(); 
    $timeout = 10; 
    $result = array(); 
    $sockets = array(); 
    $convenient_read_block = 8192; 
    $host = "test.local.com"; 
    $sql = "select waybill_id,order_id from xm_waybill where status>40 order by update_time desc limit 1 ";  
    $data = Yii::app()->db->createCommand($sql)->queryAll(); 
    $id = 0; 
 
    foreach ($data as $k => $v) { 
      if ($k % 2 == 0) { 
        $send_data[$k]['body'] = NoticeOrder::getSendData($v['waybill_id']); 
 
      } else { 
        $send_data[$k]['body'] = array($v['order_id'] => array('extra' => 16));  
      }  
      $data = json_encode($send_data[$k]['body']); 
      $s = stream_socket_client($host . ":80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT); 
      if ($s) {  
        $sockets[$id++] = $s; 
        $http_message = "GET /php/test.php?data=" . $data . " HTTP/1.0\r\nHost:" . $host . "\r\n\r\n";  
        fwrite($s, $http_message); 
      } else {  
        echo "Stream " . $id . " failed to open correctly."; 
      }  
    } 
 
    while (count($sockets)) { 
 
      $read = $sockets; 
 
      stream_select($read, $w = null, $e = null, $timeout); 
       if (count($read)) {  
        /* stream_select generally shuffles $read, so we need to 
         compute from which socket(s) we're reading. */ 
        foreach ($read as $r) { 
 
          $id = array_search($r, $sockets); 
          $data = fread($r, $convenient_read_block); 
          if (strlen($data) == 0) { 
            echo "Stream " . $id . " closes at " . date('h:i:s') . ".<br>  "; 
            fclose($r); 
             unset($sockets[$id]); 
          } else { 
            $result[$id] = $data; 
          } 
        } 
      } else {  
        /* A time-out means that *all* streams have failed 
         to receive a response. */ 
        echo "Time-out!\n"; 
        break; 
      }  
    }  
    print_r($result); 
 
  }

3、通过多进程代替多线程

function daemon($func_name,$args,$number){ 
  while(true){ 
    $pid=pcntl_fork(); 
    if($pid==-1){ 
      echo "fork process fail"; 
      exit(); 
    }elseif($pid){//创建的子进程 
 
      static $num=0; 
      $num++; 
      if($num>=$number){ 
        //当进程数量达到一定数量时候,就对子进程进行回收。 
        pcntl_wait($status); 
 
        $num--; 
      }  
    }else{ //为0 则代表是子进程创建的,则直接进入工作状态 
 
      if(function_exists($func_name)){ 
        while (true) { 
          $ppid=posix_getpid(); 
          var_dump($ppid); 
          call_user_func_array($func_name,$args); 
          sleep(2); 
        } 
      }else{ 
        echo "function is not exists"; 
      } 
      exit();   
    } 
  } 
}  
function worker($args){  
  //do something 
 
}  
daemon('worker',array(1),2);

以上就是为大家分享的三种php实现多线程类似的方法,希望对大家的学习有所帮助。

PHP 相关文章推荐
一个MYSQL操作类
Nov 16 PHP
PHP 中文乱码解决办法总结分析
Jul 30 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
Jun 04 PHP
深入php处理整数函数的详解
Jun 09 PHP
php获取目录所有文件并将结果保存到数组(实例)
Oct 25 PHP
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
Jun 12 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
Jul 25 PHP
php解析http获取的json字符串变量总是空白null
Mar 02 PHP
php pdo oracle中文乱码的快速解决方法
May 16 PHP
浅谈Yii乐观锁的使用及原理
Jul 25 PHP
Laravel5.1 框架路由基础详解
Jan 04 PHP
如何在PHP环境中使用ProtoBuf数据格式
Jun 19 PHP
php搜索文件程序分享
Oct 30 #PHP
纯php生成随机密码
Oct 30 #PHP
php利用smtp类实现电子邮件发送
Oct 30 #PHP
PHP利用APC模块实现大文件上传进度条的方法
Oct 29 #PHP
php如何实现只替换一次或N次
Oct 29 #PHP
php抓取网站图片并保存的实现方法
Oct 29 #PHP
最准确的php截取字符串长度函数
Oct 29 #PHP
You might like
十大感人催泪爱情动漫 第一名至今不忍在看第二遍
2020/03/04 日漫
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
PHP的explode和implode的使用说明
2011/07/17 PHP
使用URL传输SESSION信息
2015/07/14 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
学习jquery必备 api中英文对照的chm手册 下载
2007/05/03 Javascript
HTML5实现留言和回复页面样式
2015/07/22 Javascript
整理Javascript流程控制语句学习笔记
2015/11/29 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
将JSON字符串转换成Map对象的方法
2016/11/30 Javascript
JavaScript基本类型值-Number类型
2017/02/24 Javascript
微信小程序 页面传值详解
2017/03/10 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
Node.js创建HTTP文件服务器的使用示例
2018/05/11 Javascript
ES6 系列之 WeakMap的使用示例
2018/08/06 Javascript
react.js组件实现拖拽复制和可排序的示例代码
2018/08/20 Javascript
vue-cli3 DllPlugin 提取公用库的方法
2019/04/24 Javascript
[58:42]DOTA2上海特级锦标赛C组败者赛 Newbee VS Archon第一局
2016/02/27 DOTA
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
Python threading多线程编程实例
2014/09/18 Python
python实现的文件同步服务器实例
2015/06/02 Python
python 3利用Dlib 19.7实现摄像头人脸检测特征点标定
2018/02/26 Python
python3实现多线程聊天室
2018/12/12 Python
Python3的socket使用方法详解
2020/02/18 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
Python调用JavaScript代码的方法
2020/10/27 Python
python 实现网易邮箱邮件阅读和删除的辅助小脚本
2021/03/01 Python
丝芙兰美国官网:SEPHORA美国
2016/08/03 全球购物
Java TransactionAPI (JTA) 主要包含几部分
2012/12/07 面试题
自主招生自荐信
2013/12/08 职场文书
中餐厅主管的职责范文
2014/02/04 职场文书
励志演讲稿3分钟
2014/08/21 职场文书
煤矿安全保证书
2015/02/27 职场文书
idea 在springboot中使用lombok插件的方法
2021/08/02 Java/Android
vue/cli 配置动态代理无需重启服务的方法
2022/05/20 Vue.js