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抽象工厂模式(Elgg)
Mar 21 PHP
php实现无限级分类实现代码(递归方法)
Jan 01 PHP
PHP 过滤页面中的BOM(实现代码)
Jun 29 PHP
PHP中使用FFMPEG获取视频缩略图和视频总时长实例
May 04 PHP
PHP读取汉字的点阵数据
Jun 22 PHP
PHP中set_include_path()函数相关用法分析
Jul 18 PHP
PHP实现图片批量打包下载功能
Mar 01 PHP
php生成静态页面并实现预览功能
Jun 27 PHP
Yii框架中使用PHPExcel的方法分析
Jul 25 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
Dec 02 PHP
Laravel框架源码解析之反射的使用详解
May 14 PHP
PHP笛卡尔积实现原理及代码实例
Dec 09 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
记录mysql性能查询过程的使用方法
2013/05/02 PHP
在Ubuntu 14.04上部署 PHP 环境及 WordPress
2014/09/02 PHP
php+mysql实现数据库随机重排实例
2014/10/17 PHP
Yii视图CGridView列表用法实例分析
2016/07/12 PHP
JavaScript 模拟用户单击事件
2009/12/31 Javascript
Javascript 变量作用域 两个可能会被忽略的小特性
2010/03/23 Javascript
JavaScript传递变量: 值传递?引用传递?
2011/02/22 Javascript
js 回车提交表单两种实现方法
2012/12/31 Javascript
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
2014/01/07 Javascript
js确认删除对话框效果的示例代码
2014/02/20 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
AngularJs  Using $location详解及示例代码
2016/09/02 Javascript
JS实现的点击表头排序功能示例
2017/03/27 Javascript
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
layui实现三级导航菜单
2019/07/26 Javascript
教你搭建按需加载的Vue组件库(小结)
2019/07/29 Javascript
Vue.js下拉菜单组件使用方法详解
2019/10/19 Javascript
JQuery使用属性addClass、removeClass和toggleClass实现增加和删除类操作示例
2019/11/18 jQuery
基于Cesium绘制抛物弧线
2020/11/18 Javascript
python连接字符串的方法小结
2015/07/13 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
2019/06/05 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
2019/10/09 Python
全球领先的全景影像品牌:Insta360
2019/08/21 全球购物
前台接待员岗位职责
2014/01/02 职场文书
会计大学生职业生涯规划书范文
2014/01/13 职场文书
售后服务经理岗位职责
2014/02/25 职场文书
政治思想表现评语
2014/05/04 职场文书
治超工作实施方案
2014/05/04 职场文书
公司行政专员岗位职责
2014/08/24 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
学生会自荐信
2019/05/16 职场文书
Python实现文本文件拆分写入到多个文本文件的方法
2021/04/18 Python
CSS基础详解
2021/10/16 HTML / CSS
ant design vue的form表单取值方法
2022/06/01 Vue.js