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正则的Unknown Modifier错误解决方法
Mar 02 PHP
PHP访问MYSQL数据库封装类(附函数说明)
Dec 04 PHP
php 下载保存文件保存到本地的两种实现方法
Aug 12 PHP
教你如何在CI框架中使用 .htaccess 隐藏url中index.php
Jun 09 PHP
使用纯php代码实现页面伪静态的方法
Jul 25 PHP
php实现过滤字符串中的中文和数字实例
Jul 29 PHP
PHP中的静态变量及static静态变量使用详解
Nov 05 PHP
PHP中each与list用法分析
Jan 08 PHP
Yii安装与使用Excel扩展的方法
Jul 13 PHP
Laravel统计一段时间间隔的数据方法
Oct 09 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
Dec 18 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 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
数组任意位置插入元素,删除特定元素的实例
2017/03/02 PHP
JS和函数式语言的三特性
2014/03/05 Javascript
Javascript操作表单实例讲解(下)
2016/06/20 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
详解windows下vue-cli及webpack 构建网站(二)导入bootstrap样式
2017/06/17 Javascript
Vue2.0 组件传值通讯的示例代码
2017/08/01 Javascript
vue的diff算法知识点总结
2018/03/29 Javascript
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
js实现通过开始结束控制的计时器
2019/02/25 Javascript
微信小程序引入VANT组件的方法步骤
2019/09/19 Javascript
javascript实现文字跑马灯效果
2020/06/18 Javascript
绘制微信小程序验证码功能的实例代码
2021/01/05 Javascript
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
Web服务器框架 Tornado简介
2014/07/16 Python
Python函数中的函数(闭包)用法实例
2016/03/15 Python
对numpy中轴与维度的理解
2018/04/18 Python
Python pycharm 同时加载多个项目的方法
2019/01/17 Python
Python中三元表达式的几种写法介绍
2019/03/04 Python
Python TCP通信客户端服务端代码实例
2019/11/21 Python
python3连接MySQL8.0的两种方式
2020/02/17 Python
HTML最新标准HTML5总结(必看)
2016/06/13 HTML / CSS
耐克美国官网:Nike.com
2016/08/01 全球购物
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
军训的自我鉴定
2013/12/10 职场文书
大学生职业规划论文
2014/01/11 职场文书
征婚广告词
2014/03/17 职场文书
学员自我鉴定
2014/03/19 职场文书
公司收款委托书范本
2014/09/20 职场文书
国际商务专业毕业生自我鉴定2014
2014/09/27 职场文书
公民授权委托书
2014/10/15 职场文书
2014年保安个人工作总结
2014/11/13 职场文书
2015年保险公司个人工作总结
2015/05/22 职场文书
公司保洁员管理制度
2015/08/04 职场文书
亲情作文之母爱
2019/09/25 职场文书
Nginx快速入门教程
2021/03/31 Servers
MySQL分区表管理命令汇总
2022/03/21 MySQL