PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(yè)(2)_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)大的功能但也很難被知曉,解釋起來(lái)也比較困難。 這篇文章
如果閱讀了上面的logger()例子,那么你認(rèn)為“為了雙向通信我為什么要使用協(xié)程呢? 為什么我不能只用常見的類呢?”,你這么問完全正確。上面的例子演示了基本用法,然而上下文中沒有真正的展示出使用協(xié)程的優(yōu)點(diǎn)。這就是列舉許多協(xié)程例子的 理由。正如上面介紹里提到的,協(xié)程是非常強(qiáng)大的概念,不過這樣的應(yīng)用很稀少而且常常十分復(fù)雜。給出一些簡(jiǎn)單而真實(shí)的例子很難。
在這篇文章里,我決定去做的是使用協(xié)程實(shí)現(xiàn)多任務(wù)協(xié)作。我們盡力解決的問題是你想并發(fā)地運(yùn)行多任務(wù)(或者“程序”)。不過處理器在一個(gè)時(shí)刻只能運(yùn)行 一個(gè)任務(wù)(這篇文章的目標(biāo)是不考慮多核的)。因此處理器需要在不同的任務(wù)之間進(jìn)行切換,而且總是讓每個(gè)任務(wù)運(yùn)行 “一小會(huì)兒”。
多任務(wù)協(xié)作這個(gè)術(shù)語(yǔ)中的“協(xié)作”說明了如何進(jìn)行這種切換的:它要求當(dāng)前正在運(yùn)行的任務(wù)自動(dòng)把控制傳回給調(diào)度器,這樣它就可以運(yùn)行其他任務(wù)了。這與 “搶占”多任務(wù)相反,搶占多任務(wù)是這樣的:調(diào)度器可以中斷運(yùn)行了一段時(shí)間的任務(wù),不管它喜歡還是不喜歡。協(xié)作多任務(wù)在Windows的早期版本 (windows95)和Mac OS中有使用,不過它們后來(lái)都切換到使用搶先多任務(wù)了。理由相當(dāng)明確:如果你依靠程序自動(dòng)傳回 控制的話,那么壞行為的軟件將很容易為自身占用整個(gè)CPU,不與其他任務(wù)共享。
這個(gè)時(shí)候你應(yīng)當(dāng)明白協(xié)程和任務(wù)調(diào)度之間的聯(lián)系:yield指令提供了任務(wù)中斷自身的一種方法,然后把控制傳遞給調(diào)度器。因此協(xié)程可以運(yùn)行多個(gè)其他任務(wù)。更進(jìn)一步來(lái)說,yield可以用來(lái)在任務(wù)和調(diào)度器之間進(jìn)行通信。
我們的目的是 對(duì) “任務(wù)”用更輕量級(jí)的包裝的協(xié)程函數(shù):
<?php
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();
}
}
一個(gè)任務(wù)是用 任務(wù)ID標(biāo)記一個(gè)協(xié)程。使用setSendValue()方法,你可以指定哪些值將被發(fā)送到下次的恢復(fù)(在之后你會(huì)了解到我們需要這個(gè))。 run()函數(shù)確實(shí)沒有做什么,除了調(diào)用send()方法的協(xié)同程序。要理解為什么添加beforeFirstYieldflag,需要考慮下面的代碼片 段:
復(fù)制代碼 代碼如下:<?php
function gen() {
yield 'foo';
yield 'bar';
}
$gen = gen();
var_dump($gen->send('something'));
// As the send() happens before the first yield there is an implicit rewind() call,
// so what really happens is this:
$gen->rewind();
var_dump($gen->send('something'));
// The rewind() will advance to the first yield (and ignore its value), the send() will
// advance to the second yield (and dump its value). Thus we loose the first yielded value!
通過添加 beforeFirstYieldcondition 我們可以確定 first yield 的值 被返回。
調(diào)度器現(xiàn)在不得不比多任務(wù)循環(huán)要做稍微多點(diǎn)了,然后才運(yùn)行多任務(wù):
<?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);
}
分享:php修改NetBeans默認(rèn)字體的大小在Netbeans中由于使用了Swing進(jìn)行開發(fā),所以其中界面的字體也是由Java虛擬機(jī)進(jìn)行配置而不是隨操作系統(tǒng)的。在安裝完Netbeans后默認(rèn)的字體大小是11px。而在Windows下的宋體最小支持12px。所以字體為11px就已經(jīng)無(wú)法完整顯示了。 簡(jiǎn)單的解決辦法就是將字體改大一點(diǎn)。詳細(xì)的
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁(yè)面代碼執(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語(yǔ)言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國(guó)語(yǔ)言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- 解讀Mysql中創(chuàng)建用戶帳戶的方法
- PHP從數(shù)組里篩選出重復(fù)的數(shù)據(jù)
- 用PHP程序?qū)崿F(xiàn)隨機(jī)廣告圖片顯示
- php使用curl模擬用戶登陸
- 解析php javascript 靜態(tài)化簡(jiǎn)單實(shí)例
- 詳解PHP和Java強(qiáng)強(qiáng)聯(lián)合
- 深入php-fpm的兩種進(jìn)程管理模式詳解
- PHP register_shutdown_function函數(shù)的深入解析
- 如何修改和添加Apache的默認(rèn)站點(diǎn)目錄
- 用javascript php隨機(jī)顯示圖片
- 相關(guān)鏈接:
復(fù)制本頁(yè)鏈接| 搜索PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(yè)(2)
- 教程說明:
PHP教程-PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(yè)(2)
。