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 数据库树的遍历方法
Feb 06 PHP
phpinfo 系统查看参数函数代码
Jun 05 PHP
php ftp文件上传函数(基础版)
Jun 03 PHP
深入php-fpm的两种进程管理模式详解
Jun 03 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
Jul 30 PHP
PHP多文件上传类实例
Mar 07 PHP
php带抄送和密件抄送的邮件发送方法
Mar 20 PHP
深入分析PHP优化及注意事项
Jul 04 PHP
thinkPHP中钩子的两种配置调用方法详解
Nov 11 PHP
PHP和MYSQL实现分页导航思路详解
Apr 11 PHP
PHP 网站修改默认访问文件的nginx配置
May 27 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
Jul 01 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
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
php获取apk包信息的方法
2014/08/15 PHP
pjblog修改技巧汇总
2007/03/12 Javascript
Javascript注入技巧
2007/06/22 Javascript
JS Excel读取和写入操作(模板操作)实现代码
2010/04/11 Javascript
jQuery 1.5最新版本的改进细节分析
2011/01/19 Javascript
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
2012/01/15 Javascript
用js格式化金额可设置保留的小数位数
2014/05/09 Javascript
js实现按一下删除键删除整个单词附demo
2014/09/05 Javascript
JS深度拷贝Object Array实例分析
2016/03/31 Javascript
移动端翻页插件dropload.js(支持Zepto和jQuery)
2016/07/27 Javascript
javascript实现秒表计时器的制作方法
2017/02/16 Javascript
vue项目中全局引入1个.scss文件的问题解决
2019/08/01 Javascript
js实现图片跟随鼠标移动效果
2019/10/16 Javascript
vue项目中常见问题及解决方案(推荐)
2019/10/21 Javascript
小程序如何自主实现拦截器的示例代码
2019/11/04 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
解决vux 中popup 组件Mask 遮罩在最上层的问题
2020/11/03 Javascript
pymssql ntext字段调用问题解决方法
2008/12/17 Python
仅用50行Python代码实现一个简单的代理服务器
2015/04/08 Python
Python命令启动Web服务器实例详解
2017/02/23 Python
Tensorflow中的placeholder和feed_dict的使用
2018/07/09 Python
Python编程快速上手——PDF文件操作案例分析
2020/02/28 Python
python实现opencv+scoket网络实时图传
2020/03/20 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
通过css3的filter滤镜改变png图片的颜色的示例代码
2020/05/06 HTML / CSS
全球知名的婚恋交友网站:Match.com
2017/01/05 全球购物
捷克汽车配件和工具销售网站:TorriaCars
2018/02/26 全球购物
潘多拉意大利官方网上商城:网上选购PANDORA珠宝
2018/10/07 全球购物
自荐信格式的六要素
2013/09/21 职场文书
预备党员思想汇报
2014/01/08 职场文书
电子邮箱格式怎么写
2014/01/12 职场文书
海洋科学专业求职信
2014/08/10 职场文书
学校食堂标语
2014/10/06 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
导游词之云南-元阳梯田
2019/10/08 职场文书