2014-02-10 8 views
2

PHP에서 비동기식 타임 아웃을 만들려고합니다.PHP에서 pthread를 사용하여 비동기 타임 아웃을 생성

그리고 PECL 확장 pthread를 사용하여 멀티 스레딩을 할 수 있습니다.

비동기 시간 초과는 완벽하게 작동하지만 참조는 그렇지 않습니다.

이 테스트에서는 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. 
Hello. 

누군가가 내가 잘못는지 말해 수 얻기

Bye. 
Bye. 

기대?

+2

나는 당신에 ParentClass 실제로 내부 값이 변경 것을 몰래, 복사됩니다 있도록 스레드를 시작하면, 동일한 메모리 개체를 사용하지 않을 것을 가정해야합니다. 문서에는 힌트가 있습니다. 직렬화 가능 값만 저장할 수 있습니다. 이렇게하면 실행될 때 값이 직렬화 될 것입니다. 부모 객체를 var_dump하여 동일한 객체인지 확인하십시오. – Sven

+1

@Sven Alright, 그래서 싱글 톤은 옵션입니까? 아니면 정적 클래스의 다른 종류? – Sem

+0

나는 stackable가 해결책일지도 모른다고 생각하고있다. 나는 다른 리턴을 얻었으므로 같은 대상이 아니라는 것을 이미 알고있다. http://www.php.net/manual/en/class.stackable.php – Sem

답변

7

다중 스레드 응용 프로그램에 sleep()을 사용하면 안됩니다. PHP가 호출하는 기본 구현은 프로세스 내의 스레드가 아니라 프로세스를 절전 상태로 만드는 것을 의미합니다. 마일리지가 다를 수 있습니다, 일부 구현 잘 자고 스레드가 발생할 수 있지만 당신이 할 수 없으며 그것에 의존해서는 안됩니다.

usleep은 프로세스가 아닌 스레드를 절전 모드로 만들도록 설계 되었기 때문에 다중 스레드에 더 적합하지만 스레드를 비 수신 상태로 유지합니다.

pthreads는 멀티 쓰레딩을 위해 설계된 적절한 동기화 메소드를 내장하고있어 스레드가 어떤 일이 생길 때까지 기다리는 동안 수신 상태가됩니다.

참조가 작동하지 않거나 참조가 필요하지 않습니다. 조작을 위해 여러 컨텍스트에서 오브젝트를 전달하려는 경우, 오브젝트는 pthread에서 내려야합니다.

<?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

관련 문제