国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

php基于協程實現異步的方法分析

2024-05-05 00:10:22
字體:
來源:轉載
供稿:網友

本文實例講述了php基于協程實現異步的方法。分享給大家供大家參考,具體如下:

github上php的協程大部分是根據這篇文章實現的: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.phpinclude __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響應式的編程是嚴格禁止這種等待的,所以我就參照unity3d的協程自己寫了個php版本的。上代碼:

<?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教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 张家港市| 永昌县| 怀宁县| 遵义县| 奉新县| 马公市| 汕尾市| 连南| 新密市| 锡林郭勒盟| 神农架林区| 石台县| 噶尔县| 无极县| 招远市| 新绛县| 苍南县| 宁都县| 常山县| 张掖市| 沧源| 宁武县| 禄丰县| 江油市| 万山特区| 札达县| 海门市| 镇原县| 淮阳县| 鄂伦春自治旗| 鹤壁市| 吐鲁番市| 屯昌县| 读书| 漳平市| 兴文县| 蚌埠市| 宿迁市| 渭南市| 平江县| 大兴区|