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 相关文章推荐
在线竞拍系统的PHP实现框架(一)
Oct 09 PHP
php性能优化分析工具XDebug 大型网站调试工具
May 22 PHP
PHP sprintf() 函数的应用(定义和用法)
Jun 29 PHP
php中选择什么接口(mysql、mysqli)访问mysql
Feb 06 PHP
解析php 版获取重定向后的地址(代码)
Jun 26 PHP
ThinkPHP分页类使用详解
Mar 05 PHP
php实现的click captcha点击验证码类实例
Sep 23 PHP
FleaPHP框架数据库查询条件($conditions)写法总结
Mar 19 PHP
Yii控制器中filter过滤器用法分析
Jul 15 PHP
PHP防止图片盗用(盗链)的方法小结
Nov 11 PHP
PHP 实现页面静态化的几种方法
Jul 23 PHP
php中青蛙跳台阶的问题解决方法
Oct 14 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
PHP 地址栏信息的获取代码
2009/01/07 PHP
php whois查询API制作方法
2011/06/23 PHP
php session安全问题分析
2011/06/24 PHP
php中将数组存到文件里的实现代码
2012/01/19 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
2014/03/25 PHP
PHP实现动态柱状图改进版
2015/03/30 PHP
javascript的键盘控制事件说明
2008/04/15 Javascript
javascript 关闭IE6、IE7
2009/06/01 Javascript
XHTML下,JS浮动代码失效的问题
2009/11/12 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
js实现杯子倒水问题自动求解程序
2013/03/25 Javascript
javascript在myeclipse中报错的解决方法
2013/10/29 Javascript
简介JavaScript中toUpperCase()方法的使用
2015/06/06 Javascript
JS+html5 canvas实现的简单绘制折线图效果示例
2017/03/13 Javascript
学习使用Bootstrap页面排版样式
2017/05/11 Javascript
详解用vue.js和laravel实现微信支付
2017/06/23 Javascript
vue2.0设置proxyTable使用axios进行跨域请求的方法
2017/10/19 Javascript
javascript计算对象长度的方法
2017/10/25 Javascript
vue watch深度监听对象实现数据联动效果
2018/08/16 Javascript
用jQuery实现抽奖程序
2020/04/12 jQuery
如何配置vue.config.js 处理static文件夹下的静态文件
2020/06/19 Javascript
Python函数中定义参数的四种方式
2014/11/30 Python
python计算方程式根的方法
2015/05/07 Python
Django与遗留的数据库整合的方法指南
2015/07/24 Python
Python中MySQLdb和torndb模块对MySQL的断连问题处理
2015/11/09 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
Python代码缩进和测试模块示例详解
2018/05/07 Python
Python2与Python3的区别实例总结
2019/04/17 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
Nike加拿大官网:Nike.com (CA)
2019/04/09 全球购物
《记金华的双龙洞》教学反思
2014/04/19 职场文书
小学生节约用水倡议书
2014/05/15 职场文书
爱我中华演讲稿
2014/05/20 职场文书
运动会方阵口号
2014/06/07 职场文书
《为人民服务》教学反思
2016/02/20 职场文书