2014-02-10 19 views
2

我试图在PHP中创建某种异步超时。使用pthreads在PHP中创建异步超时

而且我正在使用PECL扩展pthreads来完成多线程操作。

异步超时工作完美,但引用没有。

我使用PHP 5.5.8进行此测试。

class ParentClass { 
    public $test; 

    public function __construct(){ 
    } 

    public function test() { 
     echo $this->test; 
    } 
} 

class Timeout extends Thread { 
    private $seconds; 
    private $parent; 

    public function __construct($seconds, &$parent){ 
     $this->seconds = $seconds; 
     $this->parent = $parent; 
    } 

    public function run(){ 
     sleep($this->seconds); 
     $this->parent->test(); 
    } 
} 

$parent = new ParentClass(); 
$parent->test = "Hello.\n"; 
$timeout = new Timeout(2, $parent); 
$timeout->start(); 
$parent->test = "Bye.\n"; 
$parent->test(); 

期待

Bye. 
Bye. 

获取

Bye. 
Hello. 

有人能告诉我什么,我做错了什么?

+2

我必须假设开始一个线程不会使用相同的内存对象,所以你的ParentClass实际上被复制,而不会注意到内部值的变化。文档中有一个提示:只能存储可序列化的值 - 这使我认为值在执行时会被序列化。你应该var_dump父类来检查它是否是相同的对象 – Sven

+1

@Sven好吧,所以单身是一种选择?或者其他一些静态类? – Sem

+0

我有想法堆栈可能是解决方案..我已经知道这是不同的对象,因为我得到不同的回报。 http://www.php.net/manual/en/class.stackable.php – Sem

回答

7

对于多线程应用程序,不应该使用sleep(),PHP调用的底层实现是为了让进程进入休眠状态,而不是进程内的线程。里程会有所不同,有些实现可能会导致线程进入睡眠状态,但您不能也不应该依赖它。

usleep更适合于多线程,因为它旨在使线程进入睡眠状态,而不是进程,但是,它也使线程处于非接受状态。

pthreads内置适当的同步方法,专为多线程而设计,让线程处于接受状态,同时等待某些事情发生。

如果您希望在多个上下文之间传递对象进行操作,则引用不起作用,也不需要,对象应该从pthreads下降。

<?php 
define("SECOND", 1000000); 

class ParentClass extends Stackable { 

    public function test() { 
     echo $this->test; 
    } 

    public function run(){} 

    public $test; 
} 

class Timeout extends Thread { 

    public function __construct($seconds, $parent){ 
     $this->seconds = $seconds; 
     $this->parent = $parent; 
    } 

    public function run(){ 
     $this->synchronized(function(){ 
      $this->wait(
       SECOND * $this->seconds); 
     }); 
     $this->parent->test(); 
    } 

    private $seconds; 
    private $parent; 
} 

$parent = new ParentClass(); 
$parent->test = "Hello.\n"; 
$timeout = new Timeout(2, $parent); 
$timeout->start(); 
$parent->test = "Bye.\n"; 
$parent->test(); 
+0

感谢您的答案! :)我一定会在下次使用它。 – Sem