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


Why are these pthreads segmentation faults possible?

在pthreads的介绍中,我读到:

当程序员调用Thread::start时,会创建一个新线程,初始化一个PHP解释器上下文,然后(安全地)对其进行操作,以镜像调用::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();

上面的例子总是会出错;步骤1-3是完全正常的,但在Worker启动之前,堆叠的对象会被删除,导致Worker被允许启动时出现segfault。

问题是:

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

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

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

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

http://php.net/Pool