PHP线程应如何存储其数据? [英] How should a PHP thread store its data?

查看:48
本文介绍了PHP线程应如何存储其数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在网上搜索和阅读有关PHP pthreads3及其应如何存储数据的信息. (或更确切地说,它们不是) 在我看来,线程正确存储其数据的唯一方法是创建一个新的Threaded对象并将其发送给线程.然后,线程可以使用此Threaded对象存储几乎所有数据.

So I have been googling and reading up and down the internet about PHP pthreads3 and how they are supposed to store data. (Or rather, how they are not) It seems to me that the only way for a thread to store its data properly is to create a new Threaded object and send it to the thread. The thread can then use this Threaded object to store nearly any data.

我的问题,以及与掌握PHP线程有关的最大问题: 是否可以在需要时让线程创建自己的存储对象? 我不知道如何或为什么,因为我在此找到的所有答案都含糊不清,详尽而令人困惑,也许,但没有",主要与性能差和内存问题/安全性有关. 看来这应该是可行的,

My question, and biggest issue with grasping PHP threads: Is it possible to have the thread create its own storage objects when it wants? I have no idea how or why, since all the answer I've found on this tell a vague, elaborate and confusing "maybe, but no", mostly related to poor performance and memory issues/safety. This seems like it should be possible, somehow:

class someFantasticThread extends Thread {
    public $someData;

    function run(){
        while(true){
            //Create a fresh storage for the new data this iteration
            $this->someData = new SomeCoolStorage(); // Can this work somehow without all the issues?
            $this->someData[] = 'amazingdata'; // Do something amazing and store the new results in $someData
            $this->someData[] = new SomeCoolStorage(); // This would also be desireable, if it can somehow be done
            //don't mind the obvious loop issues. Imagine this is a well formed loop
        }
    }
}

class SomeCoolStorage extends Threaded{}

// Start the thread
$threadObj = new someFantasticThread();
$threadObj->start();
while(true){
    // at some point, retrieve the data and do something useful with the contained results
    // doSomethingAwesome($threadObj->someData);
}

推荐答案

在我看来,线程正确存储其数据的唯一方法是创建一个新的Threaded对象并将其发送到线程.

It seems to me that the only way for a thread to store its data properly is to create a new Threaded object and send it to the thread.

是的,这是一种方法.

是否可以让线程在需要时创建自己的存储对象?

Is it possible to have the thread create its own storage objects when it wants?

是的,但前提是您必须在该线程(或它可能产生的任何子线程)中对其进行操作.

Yes, but only if you manipulate it within that thread (or any child threads it may spawn).

在PHP中使用线程时要理解的基本知识之一是Threaded的对象与创建它们的上下文相关联.这意味着,如果您在主线程中创建一个Threaded对象,将该对象传递给一个生成的子线程,然后加入该生成的子线程,那么您可以继续照常使用该Threaded对象.

One of the fundamental things to understand when using threads in PHP is that objects of a Threaded class are tied to the context in which they are created. This means that if you create a Threaded object in the main thread, pass this object into a spawned child thread, and then join that spawned child thread, then you may continue to use that Threaded object as normal.

示例1(构造函数注入):

Example 1 (constructor injection):

<?php

$store = new Threaded(); // created in the main thread

$thread = new class($store) extends Thread {
    public $store;

    public function __construct(Threaded $store)
    {
        $this->store = $store;
    }

    public function run()
    {
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($store); // continue using it in the main thread

这将输出:

Threaded Object
(
    [0] => 1
    [1] => 2
)

在上面的示例中,我们还可以在构造函数内部创建Threaded对象,然后在脚本末尾执行var_dump($thread->store);.之所以起作用,是因为Threaded对象仍在需要它的最外层范围中创建,因此它并不与可能已经被破坏的任何子线程的范围相关. (PHP中Thread中唯一在单独线程中执行的部分是Thread::run方法.)

In the example above, we could also have created the Threaded object inside of the constructor, and then performed a var_dump($thread->store); at the end of the script. This works because the Threaded object is still being created in the outermost scope in which it is needed, and thus it is not tied to the scope of any child threads that may have already been destroyed. (The only part of a Thread in PHP that is executed in a separate thread is the Thread::run method.)

类似于以上示例,我们也可以使用二传手注入. (尽管如此,只要在使用Threaded对象的最外部作用域中的线程调用了setter即可.)

Similar to the above example, we could also have used setter injection. (Though, again, just so long as the setter is being called by the thread in the outer most scope in which the Threaded object will be used.)

许多不熟悉PHP线程的开发人员似乎遇到的问题是,当他们从新线程内部创建Threaded对象时,他们期望当他们在新线程中使用该Threaded对象时,已经加入了同一线程.

The problem that many developers who are new to threading in PHP seem to encounter, is when they create a Threaded object from inside of a new thread, and then expect to be able to use that Threaded object when they have joined that same thread.

示例:

<?php

$thread = new class() extends Thread {
    public $store;

    public function run()
    {
        $this->store = new Threaded(); // created inside of the child thread
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($thread->store); // attempt to use it in the outer context (the main thread)

这将输出:

RuntimeException:pthreads检测到尝试连接到已在%s:%d中销毁的对象

RuntimeException: pthreads detected an attempt to connect to an object which has already been destroyed in %s:%d

这是因为加入派生的子线程时,$thread->store中的Threaded对象已被破坏.这个问题也可能更加微妙.例如,在Threaded对象内部创建新数组将自动将它们强制转换为Volatile对象(也是Threaded对象).

This is because the Threaded object in $thread->store has been destroyed when joining the spawned child thread. This problem can be far more subtle, too. For example, creating new arrays inside of Threaded objects will automatically cast them to Volatile objects (which are also Threaded objects).

这意味着以下示例也将不起作用:

This means that the following example will not work either:

<?php

$thread = new class() extends Thread {
    public $store;

    public function run()
    {
        $this->store = [];
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($thread->store);

输出:

RuntimeException:pthreads检测到尝试连接到已在%s:%d中销毁的对象

RuntimeException: pthreads detected an attempt to connect to an object which has already been destroyed in %s:%d

回到示例代码,您所做的事情绝对没问题,但前提是您不尝试在该子线程之外使用$this->someData.

To come back to your example code, what you're doing is absolutely fine, but only so long as you do not attempt to use $this->someData outside of that child thread.

这篇关于PHP线程应如何存储其数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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