PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(3)_PHP教程
推薦:PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)PHP5.5一個(gè)比較好的新功能是實(shí)現(xiàn)對(duì)生成器和協(xié)同程序的支持。對(duì)于生成器,PHP的文檔和各種其他的博客文章(就像這一個(gè)或這一個(gè))已經(jīng)有了非常詳細(xì)的講解。協(xié)同程序相對(duì)受到的關(guān)注就少了,所以協(xié)同程序雖然有很強(qiáng)大的功能但也很難被知曉,解釋起來也比較困難。 這篇文章
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);
}
}
}
}
newTask()方法(使用下一個(gè)空閑的任務(wù)id)創(chuàng)建一個(gè)新任務(wù),然后把這個(gè)任務(wù)放入任務(wù)映射數(shù)組里。接著它通過把任務(wù)放入任務(wù)隊(duì)列里來實(shí)現(xiàn) 對(duì)任務(wù)的調(diào)度。接著run()方法掃描任務(wù)隊(duì)列,運(yùn)行任務(wù)。如果一個(gè)任務(wù)結(jié)束了,那么它將從隊(duì)列里刪除,否則它將在隊(duì)列的末尾再次被調(diào)度。
讓我們看看下面具有兩個(gè)簡單(并且沒有什么意義)任務(wù)的調(diào)度器:
<?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();
兩個(gè)任務(wù)都僅僅回顯一條信息,然后使用yield把控制回傳給調(diào)度器。輸出結(jié)果如下:
復(fù)制代碼 代碼如下:
This is task 1 iteration 1.
This is task 2 iteration 1.
This is task 1 iteration 2.
This is task 2 iteration 2.
This is task 1 iteration 3.
This is task 2 iteration 3.
This is task 1 iteration 4.
This is task 2 iteration 4.
This is task 1 iteration 5.
This is task 2 iteration 5.
This is task 1 iteration 6.
This is task 1 iteration 7.
This is task 1 iteration 8.
This is task 1 iteration 9.
This is task 1 iteration 10.
輸出確實(shí)如我們所期望的:對(duì)前五個(gè)迭代來說,兩個(gè)任務(wù)是交替運(yùn)行的,接著第二個(gè)任務(wù)結(jié)束后,只有第一個(gè)任務(wù)繼續(xù)運(yùn)行。
與調(diào)度器之間通信
既然調(diào)度器已經(jīng)運(yùn)行了,那么我們就轉(zhuǎn)向日程表的下一項(xiàng):任務(wù)和調(diào)度器之間的通信。我們將使用進(jìn)程用來和操作系統(tǒng)會(huì)話的同樣的方式來通信:系統(tǒng)調(diào)用。 我們需要系統(tǒng)調(diào)用的理由是操作系統(tǒng)與進(jìn)程相比它處在不同的權(quán)限級(jí)別上。因此為了執(zhí)行特權(quán)級(jí)別的操作(如殺死另一個(gè)進(jìn)程),就不得不以某種方式把控制傳回給 內(nèi)核,這樣內(nèi)核就可以執(zhí)行所說的操作了。再說一遍,這種行為在內(nèi)部是通過使用中斷指令來實(shí)現(xiàn)的。過去使用的是通用的int指令,如今使用的是更特殊并且更 快速的syscall/sysenter指令。
我們的任務(wù)調(diào)度系統(tǒng)將反映這種設(shè)計(jì):不是簡單地把調(diào)度器傳遞給任務(wù)(這樣久允許它做它想做的任何事),我們將通過給yield表達(dá)式傳遞信息來與系統(tǒng)調(diào)用通信。這兒yield即是中斷,也是傳遞信息給調(diào)度器(和從調(diào)度器傳遞出信息)的方法。
為了說明系統(tǒng)調(diào)用,我將對(duì)可調(diào)用的系統(tǒng)調(diào)用做一個(gè)小小的封裝:
<?php
class SystemCall {
protected $callback;
public function __construct(callable $callback) {
$this->callback = $callback;
}
public function __invoke(Task $task, Scheduler $scheduler) {
$callback = $this->callback; // Can't call it directly in PHP :/
return $callback($task, $scheduler);
}
}
它將像其他任何可調(diào)用那樣(使用_invoke)運(yùn)行,不過它要求調(diào)度器把正在調(diào)用的任務(wù)和自身傳遞給這個(gè)函數(shù)。為了解決這個(gè)問題 我們不得不微微的修改調(diào)度器的run方法:
復(fù)制代碼 代碼如下:<?php
public function run() {
while (!$this->taskQueue->isEmpty()) {
$task = $this->taskQueue->dequeue();
$retval = $task->run();
分享:php修改NetBeans默認(rèn)字體的大小在Netbeans中由于使用了Swing進(jìn)行開發(fā),所以其中界面的字體也是由Java虛擬機(jī)進(jìn)行配置而不是隨操作系統(tǒng)的。在安裝完Netbeans后默認(rèn)的字體大小是11px。而在Windows下的宋體最小支持12px。所以字體為11px就已經(jīng)無法完整顯示了。 簡單的解決辦法就是將字體改大一點(diǎn)。詳細(xì)的
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁面代碼執(zhí)行時(shí)間
- PHP中獎(jiǎng)概率的抽獎(jiǎng)算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對(duì)圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問控制的和運(yùn)算符優(yōu)先級(jí)介紹
- 關(guān)于PHP語言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國語言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
- 相關(guān)鏈接:
- 教程說明:
PHP教程-PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(3)
。