PHP/pthreads Thread类不能使用数组吗? [英] A PHP/pthreads Thread class can't use array?

查看:76
本文介绍了PHP/pthreads Thread类不能使用数组吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现一个PECL pthread Thread不能使用数组对象.我该怎么办才能找到原因?

I've found a PECL pthread Thread can't use an array object. What can I do to find the cause?

代码示例:

   class my extends Thread {

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

           public function add() {
                   $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是一个没有共享的环境:这意味着每个进程(或线程)必须具有其自己的解释程序,所有模块和用户代码的副本.

The Problem

PHP is a shared nothing environment: This means that each process (or thread) must have it's own copy of the interpreter, all modules, and user code.

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

The HashTable structure which not only supports PHP arrays, but is used throughout the PHP code base, was never intended to be manipulated by multiple contexts.

每当您设置一个数组的新成员(等同于malloc),未设置一个(等同于free)或更新一个(等同于free然后malloc)时,都会调用内存管理器,它是无共享架构,除其他外,特别设计为禁止任何上下文释放由另一个上下文分配的内存,因为这构成了对无共享的侵犯.

The memory manager, which would be invoked whenever you set a new member of an array (equivalent of malloc), unset one (equivalent of free), or update one (equivalent of free then malloc), is an integral part of the shared nothing architecture, and among other things is specifically designed to disallow any context to free memory that was allocated by another context, since this constitutes a violation of shared nothing.

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

The Virtual Machine assumes that it is the only context manipulating an array.

所有扩展代码都采用相同的假设.

All extension code makes the same assumption.

忽略规则的后果-不共享任何内容-可怕:您使PHP崩溃了.

The consequences for ignoring the rules - share nothing - are dire: You crash PHP.

所有这些使您无法在多个上下文中存储和操作实际数组,并且无论如何都应使其不受欢迎.

All of this makes allowing you to store and manipulate an actual array in multiple contexts unrealisable, and should make it undesirable whatever.

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

Arrays will be serialized upon setting them as a member of a Threaded object.

您应该将数组的用法替换为Threaded对象.

You should replace your usage of arrays with Threaded objects.

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

A Threaded object can be manipulated as if it were an array.

以下是一些入门指南:

<?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对象的自动不可变性的概念.

PHP7

pthreads v3 (PHP7) introduces the concepts of automatic immutability for Threaded objects.

我的博客中关于不变性的语录pthreads v3:

Quote from my blog post on immutability in pthreads v3:

在pthreads v3中,将Threaded对象( A )的成员设置为另一个Threaded对象( B )会引用 A 保持 B 不可变.

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.

不可移植性是一种性能优化.

Immutability is a performance optimization.

显然,数组的大多数使用情况都涉及对数组进行突变,而Threaded对象现在并不总是能够支持.

Obviously most use cases for arrays involve mutating the array, which Threaded objects are now not always able to support.

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

In this particular case, none of the members of the Threaded array are Threaded.

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

pthreads v3 (PHP7) introduces the concept of Volatile objects.

易失性形容词:易于迅速且不可预测地发生变化,尤其是在情况更糟的情况下.

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

Volatile对象比Threaded对象慢,因为它们不能从不变性允许我们进行的性能优化中受益.

Volatile objects are slower than Threaded objects because they cannot benefit from the performance optimizations that immutability allow us to make.

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

Volatile objects do serve as good alternative to arrays in pthreads v3. pthreads will coerce arrays to Volatile objects when they are set as members of Threaded objects:

<?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->arrayThread的运行时中表现正常.

This causes $this->array to behave as expected during the runtime of the Thread.

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

There is a side effect, illustrated by the output of the following code:

<?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"
}

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

Notice that the Volatile object in the Thread is disconnected from the array that was supplied to it's constructor, so that the main context is still manipulating an array.

Thread操作从另一个来源传入的数组时,自动强制用于降低每分钟的wtfs速率.

Automatic coercion serves to reduce the wtfs-per-minute rate when a Thread manipulates an array that was passed in from another source.

总是明确的总是更好;不依靠胁迫是最好的选择.

It's always better to be explicit; Not relying on coercion is the best option.

如果您已经知道某些依赖项将是数组,则在将它们设置为成员之前先进行处理,完全避免强制.

If you already know that some dependencies will be arrays, then deal with that before setting them as members, avoiding coercion entirely.

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

It is possible to avoid automatic coercion to Volatile by using an explicit cast:

<?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一样,该阵列将被序列化以进行存储.

As the example code shows, this is useful for when you really do want to use an array to store a result. As with PHP5, the array will be serialized for storage.

这篇关于PHP/pthreads Thread类不能使用数组吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆