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安装全攻略:APACHE
Oct 09 PHP
php获取网页内容方法总结
Dec 04 PHP
php5 apache 2.2 webservice 创建与配置(java)
Jan 27 PHP
Zend Studio去除编辑器的语法警告设置方法
Oct 24 PHP
支持中文和其他编码的php截取字符串函数分享(截取中文字符串)
Mar 13 PHP
php冒泡排序、快速排序、快速查找、二维数组去重实例分享
Apr 24 PHP
使用php的HTTP请求的库Requests实现美女图片墙
Feb 22 PHP
全面解读PHP的人气开发框架Laravel
Oct 15 PHP
SAE实时日志接口SDK用法示例
Oct 09 PHP
PHP获取页面执行时间的方法(推荐)
Dec 10 PHP
浅谈PHP进程管理
Mar 08 PHP
PHP重载基础知识回顾
Sep 10 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
用Zend Encode编写开发PHP程序
2006/10/09 PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
2017/02/28 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
2018/04/21 PHP
PHP PDOStatement::fetch讲解
2019/01/31 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
2019/05/08 PHP
Jquery动态更改一张位图的src与Attr的使用
2013/07/31 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
jquery获取颜色在ie和ff下的区别示例介绍
2014/03/28 Javascript
nodejs下打包模块archiver详解
2014/12/03 NodeJs
学习JavaScript设计模式(继承)
2015/11/26 Javascript
node.js require() 源码解读
2015/12/13 Javascript
js简单时间比较的方法
2016/08/02 Javascript
JS表格组件神器bootstrap table使用指南详解
2017/04/12 Javascript
Nodejs 和Session 原理及实战技巧小结
2017/08/25 NodeJs
fetch 使用及如何接收JS传值
2017/11/11 Javascript
使用 Vue 绑定单个或多个 Class 名的实例代码
2018/01/08 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
WebSocket的简单介绍及应用
2019/05/23 Javascript
微信小程序实现录制、试听、上传音频功能(带波形图)
2020/02/27 Javascript
JS数组的高级使用方法示例小结
2020/03/14 Javascript
js瀑布流布局的实现
2020/06/28 Javascript
利用Tkinter和matplotlib两种方式画饼状图的实例
2017/11/06 Python
python进程间通信Queue工作过程详解
2019/11/01 Python
如何用Matplotlib 画三维图的示例代码
2020/07/28 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
Canvas实现保存图片到本地的示例代码
2018/06/28 HTML / CSS
处理textarea中的换行和空格
2019/12/12 HTML / CSS
校领导推荐信
2013/11/01 职场文书
学历公证书范本
2014/04/09 职场文书
人力资源管理毕业生自荐信
2014/06/26 职场文书
本科毕业论文致谢词
2015/05/14 职场文书
新生开学寄语大全
2015/05/28 职场文书
个人催款函范文
2015/06/24 职场文书
SpringCloud Feign请求头删除修改的操作代码
2022/03/20 Java/Android
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS