我发现一个PECL pthread Thread不能使用数组对象.找到原因可以做些什么?

代码示例:

class my extends Thread {

           public function __construct() {
                   $this->arr = array();
                   $this->id  = 0;
           }
           pulbic function run() {
                   while (true) {
                           $this->wait();
                   }
           }

           public function set() {
                   $this->id = rand(0,1000);
                   $this->arr[] = rand(0,1000);
                   var_dump($this->id);//this is rand
                   var_dump($this->arr);//this is empty array()
                   $this->notify();
           }
   }

   $my = new my();
   $my->start();
   while (true) {
           sleep(1);
           $my->add();
   }
问题

PHP是一个没有共享的环境:这意味着每个进程(或线程)必须具有它自己的解释器,所有模块和用户代码的副本.

不仅支持PHP数组,而且在整个PHP代码库中使用的HashTable结构从来没有被多个上下文操纵.

当你设置一个数组的新成员(相当于malloc)时,会调用这个内存管理器,而不是设置一个(相当于free)或更新一个(相当于free然后malloc)的内存管理器是共享的一个组成部分架构,其中尤其是专门设计为不允许任何上下文释放由另一个上下文分配的内存,因为这构成了对共享的任何内容的违反.

虚拟机假定它是操纵数组的唯一上下文.

所有扩展代码都做出相同的假设.

忽略规则的后果 – 不分享 – 是可怕的:你崩溃了PHP.

所有这一切使得您可以在多个上下文中存储和操作实际的数组,不可剥离,并且应该使它不受欢迎.

PHP5

将数组设置为Threaded对象的成员后,将其序列化.

您应该使用Threaded对象替换数组的使用.

Threaded对象可以像数组一样被操纵.

这里有一些让你开始的事情:

<?PHP
class Test extends Thread {
    public function __construct(Threaded $storage) {
        $this->storage = $storage; 
    }

    public function run(){
        $i = 0;
        while(++$i < 10) {
            $this->storage[]=rand(0,1000);
        }

        $this->synchronized(function($thread){
            $thread->stored = true;
            $thread->notify();
        },$this);
    } 
}

$storage = new Threaded();
$my = new Test($storage);
$my->start();

$my->synchronized(function(Thread $thread){
    while (!$thread->stored) {
        $thread->wait();
    }
},$my);

var_dump($storage);
?>

PHP7

pthreads v3(PHP7)介绍了Threaded对象的自动不变性的概念.

引用我的blog帖子不变性在pthreads v3:

In pthreads v3,setting a member of a Threaded object (A) to another Threaded object (B) makes the reference that A holds to B immutable.

不变性是性能优化.

显然,数组的大多数用例涉及到突变数组,哪些Threaded对象现在并不总是能够支持.

在这种特殊情况下,Threaded数组的所有成员都不是Threaded的.

pthreads v3(PHP7)引入了Volatile对象的概念.

Volatile,Adjective: Liable to change rapidly and unpredictably,especially for the worse.

易失性对象比Threaded对象慢,因为它们不能从不变性允许我们做出的性能优化中受益.

易失性对象可以很好地替代pthreads v3中的数组.当将它们设置为Threaded对象的成员时,pthreads会将数组强制转换为Volatile对象:

<?PHP
class Test extends Thread {
    public function run(){
        $array = [
            "Hello","World"
        ];

        var_dump($array);

        $this->array = $array;

        var_dump($this->array);
    } 
}

$test = new test();
$test->start() && $test->join();
?>

会产生:

array(2) {
  [0]=>
  string(5) "Hello"
  [1]=>
  string(5) "World"
}
object(Volatile)#2 (2) {
  [0]=>
  string(5) "Hello"
  [1]=>
  string(5) "World"
}

这导致$this->数组在Thread的运行时期间按预期的方式运行.

有一个副作用,由以下代码的输出说明:

<?PHP
class Test extends Thread {
    public function __construct(array $array) {
        $this->array = $array;
    }

    public function run(){
        var_dump($this->array);
    } 
}

$array = [
    "Hello","World"
];
$test = new Test($array);
$test->start() && $test->join();
var_dump($array);
?>

会产生:

object(Volatile)#2 (2) {
  [0]=>
  string(5) "Hello"
  [1]=>
  string(5) "World"
}
array(2) {
  [0]=>
  string(5) "Hello"
  [1]=>
  string(5) "World"
}

请注意,线程中的Volatile对象与提供给其构造函数的数组断开连接,因此主上下文仍在操纵数组.

当线程操纵从另一个源传递的数组时,自动强制用于减少每分钟wtfs的速率.

总是更好地明确;不依赖强制是最好的选择.

如果您已经知道一些依赖关系将是数组,那么在将它们设置为成员之前,将其处理,从而完全避免强制.

可以通过使用显式转换来避免对Volatile的自动强制:

<?PHP
class Test extends Thread {
    public function run() {
        $this->result = (array) [
            "Hello" => "World"
        ];
    }
}

$test = new test();
$test->start() && $test->join();
var_dump($test->result);
?>

会屈服

array(1) {
  ["Hello"]=>
  string(5) "World"
}

如示例代码所示,当您真正想要使用数组来存储结果时,这很有用.与PHP5一样,数组将被序列化存储.

PHP / pthreads Thread类不能使用数组?的更多相关文章

  1. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  2. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  6. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  7. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  8. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

  9. ios – NSArray indexOfObject返回nil

    任何想法为什么我不能得到一个我确定在数组中存在的对象的索引?相反,我没有……

  10. ios – 上下文类型’NSFastEnumeration’不能与数组文字一起使用

    斯威夫特3,你会这样做吗?解决方法正如您所发现的,您不能使用as-casting将数组文字的类型指定为NSFastEnumeration.您需要找到一个符合NSFastEnumeration的正确类,在您的情况下它是NSArray.通常写这样的东西:

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部