PHP 线程应该如何存储它的数据?
How should a PHP thread store its data?
所以我一直在网上搜索和阅读有关 PHP pthreads3 以及它们应该如何存储数据的信息。 (或者更确切地说,他们不是)
在我看来,线程正确存储其数据的唯一方法是创建一个新的 Threaded 对象并将其发送给线程。然后线程可以使用这个 Threaded 对象来存储几乎所有数据。
我的问题,也是掌握PHP线程的最大问题:
是否可以让线程在需要时创建自己的存储对象?
我不知道如何或为什么,因为我在这个问题上找到的所有答案都含糊、详尽和令人困惑 "maybe, but no",主要与性能和内存不佳有关 issues/safety。
这似乎应该是可能的,不知何故:
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);
}
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?
是的,但前提是您在该线程(或它可能产生的任何子线程)中操作它。
在 PHP 中使用线程时要理解的基本事情之一是 Threaded
class 的对象与它们所在的上下文相关联创建。这意味着,如果您在主线程中创建一个 Threaded
对象,将此对象传递给派生的子线程,然后加入该派生的子线程,那么您可以继续正常使用该 Threaded
对象.
示例 1(构造函数注入):
<?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
方法。)
类似于上面的例子,我们也可以使用setter注入。 (尽管如此,只要 setter 被最外层范围内的线程调用,其中将使用 Threaded
对象。)
许多刚接触 PHP 线程的开发人员似乎遇到的问题是,当他们从新线程内部创建一个 Threaded
对象,然后期望能够当他们加入同一个线程时使用那个 Threaded
对象。
示例:
<?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 detected an attempt to connect to an object which has already been destroyed in %s:%d
这是因为 $thread->store
中的 Threaded
对象在加入生成的子线程时已被销毁。这个问题也可能更加微妙。例如,在 Threaded
对象中创建新数组会自动将它们转换为 Volatile
对象(也是 Threaded
对象)。
这意味着下面的例子也不行:
<?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 detected an attempt to connect to an object which has already been destroyed in %s:%d
回到您的示例代码,您所做的绝对没问题,但前提是您不尝试在该子线程之外使用 $this->someData
。
所以我一直在网上搜索和阅读有关 PHP pthreads3 以及它们应该如何存储数据的信息。 (或者更确切地说,他们不是) 在我看来,线程正确存储其数据的唯一方法是创建一个新的 Threaded 对象并将其发送给线程。然后线程可以使用这个 Threaded 对象来存储几乎所有数据。
我的问题,也是掌握PHP线程的最大问题: 是否可以让线程在需要时创建自己的存储对象? 我不知道如何或为什么,因为我在这个问题上找到的所有答案都含糊、详尽和令人困惑 "maybe, but no",主要与性能和内存不佳有关 issues/safety。 这似乎应该是可能的,不知何故:
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);
}
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?
是的,但前提是您在该线程(或它可能产生的任何子线程)中操作它。
在 PHP 中使用线程时要理解的基本事情之一是 Threaded
class 的对象与它们所在的上下文相关联创建。这意味着,如果您在主线程中创建一个 Threaded
对象,将此对象传递给派生的子线程,然后加入该派生的子线程,那么您可以继续正常使用该 Threaded
对象.
示例 1(构造函数注入):
<?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
方法。)
类似于上面的例子,我们也可以使用setter注入。 (尽管如此,只要 setter 被最外层范围内的线程调用,其中将使用 Threaded
对象。)
许多刚接触 PHP 线程的开发人员似乎遇到的问题是,当他们从新线程内部创建一个 Threaded
对象,然后期望能够当他们加入同一个线程时使用那个 Threaded
对象。
示例:
<?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 detected an attempt to connect to an object which has already been destroyed in %s:%d
这是因为 $thread->store
中的 Threaded
对象在加入生成的子线程时已被销毁。这个问题也可能更加微妙。例如,在 Threaded
对象中创建新数组会自动将它们转换为 Volatile
对象(也是 Threaded
对象)。
这意味着下面的例子也不行:
<?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 detected an attempt to connect to an object which has already been destroyed in %s:%d
回到您的示例代码,您所做的绝对没问题,但前提是您不尝试在该子线程之外使用 $this->someData
。