PHP Pthread-cand';取不到文件
我正在尝试编写php线程。我正在构造函数中创建一个DOMDocument,但是由于某种原因,新创建的文档虽然分配给了一个成员变量,但是消失了 代码清单1:PHP Pthread-cand';取不到文件,php,pthreads,Php,Pthreads,我正在尝试编写php线程。我正在构造函数中创建一个DOMDocument,但是由于某种原因,新创建的文档虽然分配给了一个成员变量,但是消失了 代码清单1: class workerThread extends Thread { private $document; private $i; public function __construct($i){ $this->document = new DOMDoc
class workerThread extends Thread {
private $document;
private $i;
public function __construct($i){
$this->document = new DOMDocument();
$this->i = $i;
}
public function run(){
try{
$root = $this->document->createElement("Root");//can't fetch this
$this->document->appendChild($root);
}catch(RuntimeException $e){
return false;
}
}
public function getRoot(){
return $this->document->documentElement;
}
}
for($i=0;$i<10;$i++){
$workers[$i] = new workerThread($i);
$workers[$i]->start();
}
for($i=0;$i<10;$i++){
$workers[$i]->join();
}
?>
我希望能够在线程外部或内部(无论是在构造函数、运行函数还是其他函数中)创建DOMDocument,在运行函数中使用它,并从处理它的线程外部检索它的根
class workerThread extends Thread {
private $document;
private $i;
public function __construct($i){
$this->document = new DOMDocument();
$this->i = $i;
}
public function run(){
try{
$root = $this->document->createElement("Root");//can't fetch this
$this->document->appendChild($root);
$this->xml = $this->document->saveXML(); // <---
}catch(RuntimeException $e){
return false;
}
}
public function getRoot(){
return $this->document->documentElement;
}
}
for($i=0;$i<10;$i++){
$workers[$i] = new workerThread($i);
$workers[$i]->start();
}
for($i=0;$i<10;$i++){
$workers[$i]->join();
$workers[$i]->xml; // <---
}
请阅读完整文档问题是该类无法可靠地序列化。根据功能手册:
请注意,许多内置PHP对象无法序列化。但是,具有这种能力的人要么实现可序列化接口,要么实现magic _sleep()和_wakeup()方法。如果一个内部类不满足这些要求中的任何一个,它就不能可靠地序列化
正如我们所看到的,DOMDocument
类(以及它的父类,DOMNode
)没有实现可序列化接口,也没有实现所需的sleep
和wakeup
方法。因此,我们不应该序列化DOMDocument
类
那么,序列化与这个问题有什么关系呢?pthreads在内部序列化所有非线程化的类(除了闭包)和线程化的对象的属性数组。这意味着在将新的DOMDocument
对象分配给workerThread::$document
属性时,pthreads会在内部序列化此属性并将其存储为字符串。获取此属性时,pthreads将其取消序列化,以便正常使用。(这只是pthreads为了在多线程环境中安全工作而必须采用的众多黑客之一。)
因此,在构造函数内部、类外部或workerThread::run
方法内部分配此属性并不重要,但仍然会遇到相同的问题
那么,解决办法是什么呢?嗯,你可以做几件事。您可以只将生成的XML保存到workerThread::$document
属性,也可以使用可序列化的友好类扩展DOMDocument类,并将其用于workerThread::$document
属性。最终,这两种解决方案都要求您将DOMDocument对象转换为XML,因为这是将其存储为线程化
属性(直接或间接)的唯一安全方法
应用第一个(也是更简单的)解决方案,下面是workerThread
类的工作版本:
class workerThread extends Thread
{
private $document;
private $i;
public function __construct($i)
{
$this->i = $i;
}
public function run()
{
$document = new DOMDocument();
try {
$root = $document->createElement("Root");
$document->appendChild($root);
} catch (RuntimeException $e) {
return false;
}
$this->document = $document->saveXML();
}
public function getRoot()
{
$document = new DOMDocument();
$document->loadXML($this->document);
return $document->documentElement;
}
}
这个解决方案是错误的(见我下面的答复)。另外,你链接到的博客文章已经过时了,目标是pthreadsv2(不再受支持)。v3需要php7.v2php5,v3php7。这是一个不断变化的性能和php版本。代码是有效的。
class workerThread extends Thread {
private $document;
private $i;
public function __construct($i){
$this->document = new DOMDocument();
$this->i = $i;
}
public function run(){
try{
$root = $this->document->createElement("Root");//can't fetch this
$this->document->appendChild($root);
$this->xml = $this->document->saveXML(); // <---
}catch(RuntimeException $e){
return false;
}
}
public function getRoot(){
return $this->document->documentElement;
}
}
for($i=0;$i<10;$i++){
$workers[$i] = new workerThread($i);
$workers[$i]->start();
}
for($i=0;$i<10;$i++){
$workers[$i]->join();
$workers[$i]->xml; // <---
}
<?php
class SearchGoogle extends Thread
{
public function __construct($query)
{
$this->query = $query;
}
public function run()
{
$this->html = file_get_contents('http://google.fr?q='.$this->query);
}
}
$job = new SearchGoogle('cats');
$job->start();
// Wait for the job to be finished and print results
$job->join();
echo $job->html;
class workerThread extends Thread
{
private $document;
private $i;
public function __construct($i)
{
$this->i = $i;
}
public function run()
{
$document = new DOMDocument();
try {
$root = $document->createElement("Root");
$document->appendChild($root);
} catch (RuntimeException $e) {
return false;
}
$this->document = $document->saveXML();
}
public function getRoot()
{
$document = new DOMDocument();
$document->loadXML($this->document);
return $document->documentElement;
}
}