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留言本实例代码
May 09 PHP
php file_exists 检查文件或目录是否存在的函数
May 10 PHP
PHP中的integer类型使用分析
Jul 27 PHP
php函数之子字符串替换&amp;#65279; str_replace
Mar 23 PHP
php错误提示failed to open stream: HTTP request failed!的完美解决方法
Jun 06 PHP
基于php-fpm 参数的深入理解
Jun 03 PHP
解析如何用php screw加密php源代码
Jun 20 PHP
php计算title标题相似比的方法
Jul 29 PHP
php处理带有中文URL的方法
Jul 11 PHP
php记录搜索引擎爬行记录的实现代码
Mar 02 PHP
thinkPHP框架中执行事务的方法示例
May 31 PHP
Laravel 简单实现Ajax滚动加载示例
Oct 22 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数组函数序列之array_sum() - 计算数组元素值之和
2011/10/29 PHP
php生成zip压缩文件的方法详解
2013/06/09 PHP
JQuery 解析多维的Json数据格式
2009/11/02 Javascript
html中的input标签的checked属性jquery判断代码
2012/09/19 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
2014/02/08 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
2014/03/13 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
小程序开发实战:实现九宫格界面的导航的代码实现
2017/01/19 Javascript
Vue2.0 组件传值通讯的示例代码
2017/08/01 Javascript
AngularJS中scope的绑定策略实例分析
2017/10/30 Javascript
vue.js使用v-if实现显示与隐藏功能示例
2018/07/06 Javascript
vue内置组件transition简单原理图文详解(小结)
2018/07/12 Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
2018/11/25 Javascript
jQuery分组选择器简单用法示例
2019/04/04 jQuery
微信小程序与公众号实现数据互通的方法
2019/07/25 Javascript
Object.keys() 和 Object.getOwnPropertyNames() 的区别详解
2020/05/21 Javascript
[01:19:34]2014 DOTA2国际邀请赛中国区预选赛 New Element VS Dream time
2014/05/22 DOTA
python 输出一个两行字符的变量
2009/02/05 Python
使用python实现strcmp函数功能示例
2014/03/25 Python
零基础写python爬虫之打包生成exe文件
2014/11/06 Python
Python模拟浏览器上传文件脚本的方法(Multipart/form-data格式)
2018/10/22 Python
python hough变换检测直线的实现方法
2019/07/12 Python
Python 实现向word(docx)中输出
2020/02/13 Python
pandas中ix的使用详细讲解
2020/03/09 Python
Python读取ini配置文件传参的简单示例
2021/01/05 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
盛大二次面试题
2016/11/18 面试题
银行出纳岗位职责
2013/11/25 职场文书
cf战队收人广告词
2014/03/14 职场文书
论群众路线学习心得体会
2014/10/31 职场文书
实习计划书范文
2015/01/16 职场文书
教师工作能力自我评价
2015/03/04 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript