php 협 정 을 바탕 으로 비동기 적 인 방법 분석
github 에서 phop 의 협 정 은 대부분 이 글 에 따라 이 루어 집 니 다.http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html。
이들 의 최종 결 과 는 우아 한 순서 로 실 행 된 코드 로 바 뀌 었 지만 막 힌 것 은 진정한 비동기 가 아니다.
예 를 들 어 가장 핫 한 것:https://github.com/recoilphp/recoil
먼저 설치:
composer require recoil/recoil
실행:
<?php
//recoil.php
include __DIR__ . '/vendor/autoload.php';
use Recoil\React\ReactKernel;
$i = 100000;
ReactKernel::start(task1());
ReactKernel::start(task2());
function task1(){
global $i;
echo "wait start" . PHP_EOL;
while ($i-- > 0) {
yield;
}
echo "wait end" . PHP_EOL;
};
function task2(){
echo "Hello " . PHP_EOL;
yield;
echo "world!" . PHP_EOL;
}
결과:wait start
//몇 초 를 기다리다
wait end
Hello
world!
나 는 원래 두 가지 임 무 를 병행 시 키 려 고 했 는데,결국 두 가지 임 무 는 직렬 로 바 뀌 었 고,중간 에 기다 리 는 시간 에는 아무 일 도 할 수 없 었 다.React 응답 식 프로 그래 밍 은 이러한 기다 림 을 엄 격 히 금지 하기 때문에 저 는 유 니 티 3d 의 협 정 을 참조 하여 phop 버 전 을 썼 습 니 다.상위 코드:
<?php
//Coroutine.php
// swoole ,
class Coroutine
{
// , ms
const TICK_INTERVAL = 1;
private $routineList;
private $tickId = -1;
public function __construct()
{
$this->routineList = [];
}
public function start(Generator $routine)
{
$task = new Task($routine);
$this->routineList[] = $task;
$this->startTick();
}
public function stop(Generator $routine)
{
foreach ($this->routineList as $k => $task) {
if($task->getRoutine() == $routine){
unset($this->routineList[$k]);
}
}
}
private function startTick()
{
swoole_timer_tick(self::TICK_INTERVAL, function($timerId){
$this->tickId = $timerId;
$this->run();
});
}
private function stopTick()
{
if($this->tickId >= 0) {
swoole_timer_clear($this->tickId);
}
}
private function run()
{
if(empty($this->routineList)){
$this->stopTick();
return;
}
foreach ($this->routineList as $k => $task) {
$task->run();
if($task->isFinished()){
unset($this->routineList[$k]);
}
}
}
}
class Task
{
protected $stack;
protected $routine;
public function __construct(Generator $routine)
{
$this->routine = $routine;
$this->stack = new SplStack();
}
/**
* [run ]
* @return [type] [description]
*/
public function run()
{
$routine = &$this->routine;
try {
if(!$routine){
return;
}
$value = $routine->current();
//
if ($value instanceof Generator) {
$this->stack->push($routine);
$routine = $value;
return;
}
//
if(!$routine->valid() && !$this->stack->isEmpty()) {
$routine = $this->stack->pop();
}
$routine->next();
} catch (Exception $e) {
if ($this->stack->isEmpty()) {
/*
throw the exception
*/
return;
}
}
}
/**
* [isFinished task ]
* @return boolean [description]
*/
public function isFinished()
{
return $this->stack->isEmpty() && !$this->routine->valid();
}
public function getRoutine()
{
return $this->routine;
}
}
테스트 코드:
<?php
//test.php
require 'Coroutine.php';
$i = 10000;
$c = new Coroutine();
$c->start(task1());
$c->start(task2());
function task1(){
global $i;
echo "wait start" . PHP_EOL;
while ($i-- > 0) {
yield;
}
echo "wait end" . PHP_EOL;
};
function task2(){
echo "Hello " . PHP_EOL;
yield;
echo "world!" . PHP_EOL;
}
결과:wait start
Hello
world!
//몇 초 기다 리 지만 막 히 지 않 습 니 다.
wait end
더 많은 PHP 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
본 논문 에서 말 한 것 이 여러분 의 PHP 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Laravel - 변환된 유효성 검사 규칙으로 API 요청 제공동적 콘텐츠를 위해 API를 통해 Laravel CMS에 연결하는 모바일 앱(또는 웹사이트) 구축을 고려하십시오. 이제 앱은 CMS에서 번역된 콘텐츠를 받을 것으로 예상되는 다국어 앱이 될 수 있습니다. 일반적으로 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.