PHP线程应如何存储其数据? [英] How should a PHP thread store its data?
问题描述
因此,我一直在网上搜索和阅读有关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屋!