php协程实现

参考文章 在PHP中使用协程实现多任务调度
书籍 现代操作系统,深入理解计算机系统,以及视频课程 linux核心技术

什么是协程?

协程可以理解为多任务用户操作系统中用户自行实现调度器的线程,也可以理解为由事件驱动的程序。
由你实现的调度器,调度运行的程序段就是协程,也有人叫协程为轻量级线程。

在多用户多任务操作系统如linux中,用户指的是使用该操作系统的操作者,也就是你开发者,可千万别理解成,web程序的客户端用户,我之前就遇到过这种小傻子。

php 协程具体实现组件

1. 任务管理器
2. 任务调度器
3. 协程堆栈

任务管理器以及任务调度器的初步实现

任务管理器
/**
 * 任务管理器
 */
class Task
{
    protected $taskId; // 任务id
    protected $coroutine; // 协程对象
    protected $sendValue = null; //
    protected $beforeFirstYield = true; // 是否为第一次调用

    public function __construct($taskId, Generator $coroutine)
    {
        $this->taskId    = $taskId;
        $this->coroutine = StackedCoroutine($coroutine);
    }

    public function getTaskId()
    {
        return $this->taskId;
    }

    public function setSendValue($sendValue)
    {
        $this->sendValue = $sendValue;
    }

    public function run()
    {
        if ($this->beforeFirstYield) {
            $this->beforeFirstYield = false;
            return $this->coroutine->current();
        }

        $retrieval = $this->coroutine->send($this->sendValue);
        $this->sendValue = null;
        return $retrieval;
    }

    /**
     * 任务是否已结束
     * @return bool
     */
    public function isFinished(): bool
    {
        return !$this->coroutine->valid();
    }
}
任务调度器
<?php
/**
 * 任务调度器
 */
class Scheduler {
    protected $maxTaskId = 0;
    protected $taskMap = []; // taskId => task
    protected $taskQueue;
    public function __construct() {
        $this->taskQueue = new SplQueue();
    }
    public function newTask(Generator $coroutine) {
        $tid = ++$this->maxTaskId;
        $task = new Task($tid, $coroutine);
        $this->taskMap[$tid] = $task;
        $this->schedule($task);
        return $tid;
    }
    public function schedule(Task $task) {
        $this->taskQueue->enqueue($task);
    }
    public function run() {
        while (!$this->taskQueue->isEmpty()) {
            $task = $this->taskQueue->dequeue();
            $task->run();
            if ($task->isFinished()) {
                unset($this->taskMap[$task->getTaskId()]);
            } else {
                $this->schedule($task);
            }
        }
    }
}
?>

初次感受协程

<?php
function task1() {
    for ($i = 1; $i <= 10; ++$i) {
        echo "This is task 1 iteration $i.\n";
        yield;
    }
}
function task2() {
    for ($i = 1; $i <= 5; ++$i) {
        echo "This is task 2 iteration $i.\n";
        yield;
    }
}
$scheduler = new Scheduler;
$scheduler->newTask(task1());
$scheduler->newTask(task2());
$scheduler->run();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值