PHP pthreads v3使用中的一些坑和注意点分析

本文实例讲述了PHP pthreads v3使用中的一些坑和注意点。分享给大家供大家参考,具体如下:

一、子线程无法访问父线程的全局变量,但父线程可以访问子线程的变量

<?php

class Task extends Thread
{
  public $data;

  public function run()
  {
    global $num;
    var_dump($num);
    $this->data = 'abc';

    //这是打印null
    var_dump($GLOBALS);
    $GLOBALS['test'] = 'def';
  }
}

//主线程中的全局变量,子线程中是无法访问的
//php中创建子线程,它会有一个单独的堆,运行在单独的地址空间中
//并不能像有些语言中,子线程是可以访问的到主线程中的变量的。
$num = 666;

$GLOBALS['test'] = 'test';

$t = new Task();
$t->start() && $t->join();

//主线程可以访问子线程的变量
var_dump($t->data);

结果如下:

二、子线程无法修改父线程的变量

<?php

class Task extends Thread
{
  private $data;

  public function __construct(&$data)
  {
    $this->data = $data;
  }

  public function run()
  {
    echo "task data : ", $this->data, "\n";
    $this->data = 'def';
    echo "task data : ", $this->data, "\n";
  }
}

$data = 'abc';

//我们这里传入的是引用
$t = new Task($data);
$t->start() && $t->join();

//但是$data变量数据并没改变
//这说明我们通过构造函数传入Task对象中的$data只是一个拷贝
//子线程中并不能够操作主线程中的变量
var_dump($data);

结果如下:

三、pthreads v3版本可以设置成员为匿名函数

<?php

class Task extends Thread
{
  private $call;

  public function __construct()
  {
    //pthreads v3版本好像可以设置成员为匿名函数
    //在v2版本中好像是不可以的
    $this->call = function ($param1, $param2) {
      echo "task call param1 : {$param1} param2 : {$param2}\n";
    };
  }

  public function run()
  {
    //直接调用成员匿名函数
    ($this->call)("hello", "world");
  }
}

$t = new Task();
$t->start() && $t->join();

结果如下:

四、对于数据库连接资源,我们需要声明为静态成员

<?php

class Task extends Thread
{
  private $db;

  public function __construct()
  {
    //注意这里会报错,不能对PDO实例进行序列化或反序列化
    $this->db = new PDO('mysql:dbname=test;host=192.168.33.226', 'root', '');
  }

  public function run()
  {
    $result = $this->db->query("select id,name from tb_user");
    while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
      echo "{$row['id']}\t{$row['name']}\n";
    }
  }
}

$t = new Task();
$t->start() && $t->join();

结果如下:

代码修改如下:

<?php

class Task extends Thread
{
  //我们需要把数据库连接资源,声明为静态成员,然后调用静态方法进行创建
  private static $db;

  //我们直接在__construct()构造函数里对$db进行实例化,好像会是null,有兴趣的可以试试
  public static function getConn()
  {
    if (!is_resource(self::$db)) {
      self::$db = new PDO('mysql:dbname=test;host=192.168.33.226', 'root', '');
    }
    return self::$db;
  }

  public function run()
  {
    $result = self::getConn()->query("select id,name from tb_user");
    while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
      echo "{$row['id']}\t{$row['name']}\n";
    }
  }
}

$t = new Task();
$t->start() && $t->join();

结果如下:

最后说明,不排除pthreads以后的版本升级上面的有些问题不会出现。

我的php版本是7.2.4,pthreads的版本是3.1.7dev

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP进程与线程操作技巧总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

(0)

相关推荐

  • PHP安装threads多线程扩展基础教程

    一.下载pthreads扩展 下载地址:http://windows.php.net/downloads/pecl/releases/pthreads 二.判断PHP是ts还是nts版 通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版. 三.根据PHP ts\nts版选择对应pthreads的版本 本人php版本是5.4.17的所以下载php_pthreads-0.1.0-5.4-t

  • PHP多线程批量采集下载美女图片的实现代码(续)

    个人认为影响的原因:匹配到的图片url并不是有效的url,文中只是简单的判断是否是相对路径,但是有些url是失效的 解决办法:就是新增判断是否是真实有效url的图片 复制代码 代码如下: /** *  *判断url是否有效  *@param $url string *@return boole  */function relUrl($url){ if(substr($url,0,4)=='http'){  $array = get_headers($url,true);  if(count($a

  • 使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)

    我之前的文章中说过,大多数网站的性能瓶颈不在PHP服务器上,因为它可以简单地通过横向增加服务器或CPU核数来轻松应对(对于各种云主机,增加VPS或CPU核数就更方便了,直接以备份镜像增加VPS,连操作系统.环境都不用安装配置),而是在于MySQL数据库. 如果用 MySQL 数据库,一条联合查询的SQL,也许就可以处理完业务逻辑,但是,遇到大量并发请求,就歇菜了. 如果用 NoSQL 数据库,也许需要十次查询,才能处理完同样地业务逻辑,但每次查询都比 MySQL 要快,十次循环NoSQL查询也许

  • php异步多线程swoole用法实例

    本文实例讲述了php异步多线程swoole用法.分享给大家供大家参考.具体分析如下: swoole重新定义PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务,下面的实例就可以证实这一功能. 一般来说,Swoole提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. swoole以前听过, 拿来做游戏服务器简直是神器-今天稍微的感受了一下,  在 ubuntu 下搭建了

  • php使用pthreads v3多线程实现抓取新浪新闻信息操作示例

    本文实例讲述了php使用pthreads v3多线程实现抓取新浪新闻信息.分享给大家供大家参考,具体如下: 我们使用pthreads,来写一个多线程的抓取页面小程序,把结果存到数据库里. 数据表结构如下: CREATE TABLE `tb_sina` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `url` varchar(256) DEFAULT '' COMMENT 'url地址', `title` varchar

  • PHP多线程类及用法实例

    本文实例讲述了PHP多线程类及用法.分享给大家供大家参考.具体分析如下: 一般来说可通过WEB服务器来实现PHP多线程功能,当然,对多线程有深入理解的人都知道通过WEB服务器实现的多线程只能模仿多线程的一些效果,并不是真正意义上的多线程. 但不管怎么样,它还是能满足我们的一些需要的,在需要类似多线程的功能方面还是可以采用这个类,代码如下: 复制代码 代码如下: /** * @title: PHP多线程类(Thread) * @version: 1.0 * * PHP多线程应用示例: * requ

  • PHP pthreads v3下的Volatile简介与使用方法示例

    本文实例讲述了PHP pthreads v3下的Volatile简介与使用方法.分享给大家供大家参考,具体如下: 由于pthreads v3中引入了Threaded对象自动不变性的概念,所以当我们在构造函数中给成员设置为数组时,在其他地方就无法对成员再次改写了. 例子如下: <?php //pthreads v3引入了Threaded对象自动不变性的概念 //如果成员被设置成Threaded对象,那么它将不能被再次改写 //当然,这主要还是为了性能优化,但有时我们又需要改写成员,那么就需要继承自

  • PHP多线程抓取网页实现代码

    受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Curl Multi Functions 它可以实现并发多线程的访问多个url地址.既然 Curl Multi Function如此强大,能否用 Curl Multi Functions 来写并发多线程下载文件呢,当然可以,下面给出我的代码: 代码1:将获得的代码直接写入某个文件 复制代码 代码如下: <?php $urls = array( 'http://www.sina.com.cn/', 'http://w

  • 实现PHP多线程异步请求的3种方法

    在网上看过很多版本的PHP异步请求方法,这里简单总结几个常用方法分享给大家 1.用CURL实现一步请求 CURL扩展是我们在开发过程中最常用的一种方法,他是一个强大的HTTP命令行工具,可以模拟POST/GET等HTTP请求,然后得到和提取数据,显示在"标准输出"(stdout)上面. 示例: 复制代码 代码如下: <?php $cl = curl_init(); $curl_opt = array(CURLOPT_URL, 'http://www.uncletoo.com/de

  • php三种实现多线程类似的方法

    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($

  • PHP Curl多线程原理实例详解

    给各位介绍一下Curl多线程实例与原理.不对之处请指教相信许多人对php手册中语焉不详的curl_multi一族的函数头疼不已,它们文档少,给的例子 更是简单的让你无从借鉴,我也曾经找了许多网页,都没见一个完整的应用例子.curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle

  • php pthreads多线程的安装与使用

    安装Pthreads 基本上需要重新编译PHP,加上 --enable-maintainer-zts 参数,但是用这个文档很少:bug会很多很有很多意想不到的问题,生成环境上只能呵呵了,所以这个东西玩玩就算了,真正多线程还是用Python.C等等 一.安装 这里使用的是 php-7.0.2 ./configure \ --prefix=/usr/local/php7 \ --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc

随机推荐