为什么这些 pthreads 分段错误是可能的?

Why are these pthreads segmentation faults possible?

this introduction to pthreads 我读到:

When the programmer calls Thread::start, a new thread is created, a PHP interpreter context is initialized and then (safely) manipulated to mirror the context that made the call to ::start.

稍后在文本中解决了 分段错误 问题。给出了这个分段错误的例子:

class W extends Worker {
    public function run(){}
}
class S extends Stackable {
    public function run(){}
}
/* 1 */
$w = new W();
/* 2 */
$j = array(
    new S(), new S(), new S()
);
/* 3 */
foreach ($j as $job)
    $w->stack($job);
/* 4 */
$j = array();
$w->start();
$w->shutdown();

The above example will always segfault; steps 1-3 are perfectly normal, but before the Worker is started the stacked objects are deleted, resulting in a segfault when the Worker is allowed to start.

题目是:

  1. 是在调用 start() 时将启动新线程的整个上下文复制到新线程中,还是仅在解释器看到对旧上下文变量的引用时才复制到新线程中?换句话说,在调用 start() 之前保持 refcounts > 0 就足够了吗?
  2. 不应该将对 Stackable 数组实体的引用存储在 Worker 对象中,以便它们在覆盖 $j 后的引用计数仍然为 1,并且不会发生段错误?

1) 线程启动时复制整个上下文。您必须保持 refcounts > 0,直到堆叠的对象被工作线程实际执行。

2) PHP 中内置变量的引用计数从未为多线程做好准备,许多 api 函数递减和递增引用计数并且没有同步(锁定)的机会。因此,您有责任维护对任何注定要由另一个线程执行的对象的引用。

这些相当烦人但不可避免的事实可以通过使用 pthreads 提供的 Pool 抽象来回避。它以适当的方式为您维护参考资料。

http://php.net/Pool