在我看来,线程正确存储其数据的唯一方法是创建一个新的 Threaded 对象并将其发送到线程。
是的,这是一种方法。
是否可以让线程在需要时创建自己的存储对象?
是的,但前提是您在该线程(或它可能产生的任何子线程)中操作它。
在 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
对象仍在需要它的最外层作用域中创建,因此它不依赖于任何可能已被销毁的子线程的作用域。 (a 的唯一部分Thread
在 PHP 中,在单独的线程中执行的是Thread::run
方法。)
与上面的示例类似,我们也可以使用 setter 注入。 (尽管如此,只要 setter 是由最外层范围内的线程调用的,在该范围内,Threaded
将使用对象。)
许多刚接触 PHP 线程的开发人员似乎遇到的问题是,当他们创建一个Threaded
从新线程内部获取对象,然后期望能够使用该对象Threaded
当他们加入同一线程时对象。
Example:
<?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 中销毁的对象的尝试
这是因为Threaded
对象在$thread->store
当加入生成的子线程时已被销毁。这个问题也可能更加微妙。例如,在内部创建新数组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);
Output:
RuntimeException:pthreads 检测到连接到已在 %s:%d 中销毁的对象的尝试
回到您的示例代码,您所做的绝对没问题,但前提是您不尝试使用$this->someData
在该子线程之外。