PHP 中的多任务调度

作者: ___n | 来源:发表于2018-01-23 17:01 被阅读12次
class Task {
    protected $taskId;
    protected $coroutine;
    protected $sendValue = null;
    protected $beforeFirstYield = true;

    public function __construct($taskId, Generator $coroutine) {
        $this->taskId = $taskId;
        $this->coroutine = $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();
        } else {
            $retval = $this->coroutine->send($this->sendValue);
            $this->sendValue = null;
            return $retval;
        }
    }

    public function isFinished() {
        return !$this->coroutine->valid();
    }
}



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();
            $retval = $task->run();

            if ($retval instanceof SystemCall) {
                $retval($task, $this);
                continue;
            }

            if ($task->isFinished()) {
                unset($this->taskMap[$task->getTaskId()]);
            } else {
                $this->schedule($task);
            }
        }
    }
    public function killTask($tid) {
        if (!isset($this->taskMap[$tid])) {
            return false;
        }

        unset($this->taskMap[$tid]);

        foreach ($this->taskQueue as $i => $task) {
            if ($task->getTaskId() === $tid) {
                unset($this->taskQueue[$i]);
                break;
            }
        }

        return true;
    }
}


class SystemCall {
    protected $callback;

    public function __construct(callable $callback) {
        $this->callback = $callback;
    }

    public function __invoke(Task $task, Scheduler $scheduler) {
        $callback = $this->callback;
        return $callback($task, $scheduler);
    }
}


function newTask(Generator $coroutine) {
    return new SystemCall(
        function(Task $task, Scheduler $scheduler) use ($coroutine) {
            $task->setSendValue($scheduler->newTask($coroutine));
            $scheduler->schedule($task);
        }
    );
}

function killTask($tid) {
    return new SystemCall(
        function(Task $task, Scheduler $scheduler) use ($tid) {
            $task->setSendValue($scheduler->killTask($tid));
            $scheduler->schedule($task);
        }
    );
}



function getTaskId() {
    return new SystemCall(function(Task $task, Scheduler $scheduler) {
        $task->setSendValue($task->getTaskId());
        $scheduler->schedule($task);
    });
}



function childTask() {
    $tid = (yield getTaskId());
    while (true) {
        echo "Child task $tid still alive!\n";
        yield;
    }
}

function task() {
    $tid = (yield getTaskId());
    $childTid = (yield newTask(childTask()));

    for ($i = 1; $i <= 6; ++$i) {
        echo "Parent task $tid iteration $i.\n";
        yield;

        if ($i == 3) yield killTask($childTid);
    }
}


$scheduler = new Scheduler;
$scheduler->newTask(task(10));
$scheduler->newTask(task(5));
$scheduler->newTask(task());
$scheduler->run();

相关文章

  • PHP 中的多任务调度

  • PHP多任务调度——进程实现

  • 学习之路 | 1 进程调度

    进程调度 多任务 Linux的进程调度 策略 策略决定调度程序在何时让什么进程运行。调度器的策略往往就决定系统的整...

  • 进程调度

    多任务 多任务系统可以划分为两类: 非抢占式多任务 除非进程自己停止, 否则它会一直执行 抢占式多任务 由调度程序...

  • 2018-09-19

    进程调度 面试的时候被问到进程调度,当时不清楚,场面一度十分尴尬,下来之后自己又复习了一下。 多任务 1.多任务操...

  • 进程调度

    这章的主要内容是进程调度相关知识,下面我们来看本章总结:多任务操系统分为两类: 非抢占式多任务 抢占式多任务Lin...

  • 8.自定义命令及任务调度

    任务调度 你的任务调度在 app/Console/Kernel.php 的 schedule 方法中进行定义。为了...

  • 【转】在PHP中使用协程实现多任务调度

    概述 协程一个异常强大的概念。原文: 鸟哥博客:http://www.laruence.com/2015/05/2...

  • 7.多任务-多线程-进程

    多任务-多线程-进程 并发:任务数多于CPU核数,通过调度算法,实现多任务一起执行,切换速度很快。宏观是任务同时运...

  • python——多任务

    linux才是真正的多用户多任务多任务,一般是通过时间片轮转和优先级调度等实现并发 进程 正在运行着的代码 线程 ...

网友评论

    本文标题:PHP 中的多任务调度

    本文链接:https://www.haomeiwen.com/subject/sbnsaxtx.html