为什么这些 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.
题目是:
- 是在调用
start()
时将启动新线程的整个上下文复制到新线程中,还是仅在解释器看到对旧上下文变量的引用时才复制到新线程中?换句话说,在调用 start()
之前保持 refcounts > 0 就足够了吗?
- 不应该将对
Stackable
数组实体的引用存储在 Worker
对象中,以便它们在覆盖 $j
后的引用计数仍然为 1,并且不会发生段错误?
1) 线程启动时复制整个上下文。您必须保持 refcounts > 0,直到堆叠的对象被工作线程实际执行。
2) PHP 中内置变量的引用计数从未为多线程做好准备,许多 api 函数递减和递增引用计数并且没有同步(锁定)的机会。因此,您有责任维护对任何注定要由另一个线程执行的对象的引用。
这些相当烦人但不可避免的事实可以通过使用 pthreads 提供的 Pool
抽象来回避。它以适当的方式为您维护参考资料。
在 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.
题目是:
- 是在调用
start()
时将启动新线程的整个上下文复制到新线程中,还是仅在解释器看到对旧上下文变量的引用时才复制到新线程中?换句话说,在调用start()
之前保持 refcounts > 0 就足够了吗? - 不应该将对
Stackable
数组实体的引用存储在Worker
对象中,以便它们在覆盖$j
后的引用计数仍然为 1,并且不会发生段错误?
1) 线程启动时复制整个上下文。您必须保持 refcounts > 0,直到堆叠的对象被工作线程实际执行。
2) PHP 中内置变量的引用计数从未为多线程做好准备,许多 api 函数递减和递增引用计数并且没有同步(锁定)的机会。因此,您有责任维护对任何注定要由另一个线程执行的对象的引用。
这些相当烦人但不可避免的事实可以通过使用 pthreads 提供的 Pool
抽象来回避。它以适当的方式为您维护参考资料。