百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> 简略的php多线程解决办法
分享文章到:

简略的php多线程解决办法

发布时间:09/01 来源:未知 浏览: 关键词:

简便的php多线程解决办法

我们在做项目的时候,有些需求,特殊是数据的响应处置需要花费大量的时间,由于php是一个短生命周期的足本说话,到了默许的30秒,php的数据处置还没完成,php的生命周期就完毕了。

这时需要使用异步并发处置战略,也就是说,一次php调取可以发出的多个恳求,这些恳求不是依照次序施行,而是可以异步并发施行的,一些恳求用于在后台处置数据,一些恳求用于接受后台响应状态,按照状态,与会员做一些简便的交互。

但是问题来了,我们都知道php本身是不支撑多线程的,那么应当如何实现php的多线程呢?

一、php模拟实现多线程的三种办法

1、linux下的php多线程

下面所讲的东西是源自php的pcntl_fork函数.由于这个函数依靠操纵系统fork的实现,所以本文所讲的东西只适用于linux/unix。那么先看看这个函数的用途吧.php手册上是这么说的:

<?php
$pid = pcntl_fork();
if ($pid == -1) {
         die('could not fork');
} else if ($pid) {
         // we are the parent
         pcntl_wait($status); //Protect against Zombie children
} else {
         // we are the child
}
?>

通过pcntl_fork创立一个子进程,假如返回值是-1的话,那么说明子进程创立失败.创立成功的进程id会返回给父进程,0返回给子进程.不好懂得吧,所以应当这样写:

<?php
$pid = pcntl_fork();
if($pid == -1){
         //创立失败咱就退出呗,没啥好说的
         die('could not fork');
}
else{
        if($pid){
                //从这里开端写的代码是父进程的,由于写的是系统程序,记得退出的时候给个返回值
                exit(0);
        }
        else{
                //从这里开端写的代码都是在新的进程里施行的,一样正常退出的话,最好也给一个返回值
                exit(0);
        }
}
?>

这样一改好懂得多了,假如你父进程但愿知道子进程正常退出的话,可以加上前面的pcntl_wait。

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
Host:" . $host . "
";  
        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!
"; 
        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的扩展 pthread 可以做到。

点此下载https://github.com/krakjoe/pthreads 但是这个下载的是 版本3 也就是php 7 才能用的,我们需要使的是 版本2

6092113c1728601303604028ac954b6.png

然后刷新的页面如下,拖到最底部:

4e53194eaffe80a031c2341653b4f32.png

5d15360dd1731d6e963293d76d50ce9.png

下一页寻到版本2的

下载下来,这个v2 才是php5才可以使用的

下载下来,安置:

或者,您直接这样下载:

cd /tools  
   wget https://github.com/krakjoe/pthreads/archive/v2.0.10.zip  
   unzip   v2.0.10.zip  
   cd pthreads-2.0.10  
   /usr/local/php/bin/phpize  
   ./configure --with-php-config=/usr/local/php/bin/php-config    
   make  
   make install

留意:您的php 在编译的时候需要开启 –enable-maintainer-zts

./configure --prefix=/usr/local/php --disable-fileinfo --enable-fpm --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-openssl --with-zlib --with-curl --enable-ftp --with-gd --with-xmlrpc --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-gd-native-ttf --enable-mbstring --with-mcrypt=/usr/local/libmcrypt --enable-zip --with-mysql=/usr/local/mysql --without-pear --enable-maintainer-zts

vim /etc/php.ini 
增加
extension=pthreads.so

重新启动php /etc/init.d/php-fpm restart

感激大家的阅读,但愿大家收益很多。

引荐教程:《php教程》

以上就是简便的php多线程解决办法的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有151人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板