PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(5)_PHP教程
推薦:PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)PHP5.5一個比較好的新功能是實現(xiàn)對生成器和協(xié)同程序的支持。對于生成器,PHP的文檔和各種其他的博客文章(就像這一個或這一個)已經(jīng)有了非常詳細的講解。協(xié)同程序相對受到的關(guān)注就少了,所以協(xié)同程序雖然有很強大的功能但也很難被知曉,解釋起來也比較困難。 這篇文章
這段代碼將打印以下信息:
復(fù)制代碼 代碼如下:Parent task 1 iteration 1.
Child task 2 still alive!
Parent task 1 iteration 2.
Child task 2 still alive!
Parent task 1 iteration 3.
Child task 2 still alive!
Parent task 1 iteration 4.
Parent task 1 iteration 5.
Parent task 1 iteration 6.
經(jīng)過三次迭代以后子任務(wù)將被殺死,因此這就是"Child is still alive"消息結(jié)束的時候。可能應(yīng)當(dāng)指出的是這不是真正的父子關(guān)系。 因為甚至在父任務(wù)結(jié)束后子任務(wù)仍然可以運行�;蛘咦尤蝿�(wù)可以殺死父任務(wù)。可以修改調(diào)度器使它具有更層級化的任務(wù)結(jié)構(gòu),不過 在這篇文章里我沒有這么做。
你可以實現(xiàn)許多進程管理調(diào)用。例如 wait(它一直等待到任務(wù)結(jié)束運行時),exec(它替代當(dāng)前任務(wù))和fork(它創(chuàng)建一個 當(dāng)前任務(wù)的克�。�。fork非�?幔夷憧梢允褂肞HP的協(xié)程真正地實現(xiàn)它,因為它們都支持克隆。
然而讓我們把這些留給有興趣的讀者吧,我們?nèi)タ聪乱粋議題。
幾點人
翻譯于 4天前
0人頂
頂 翻譯的不錯哦!
非阻塞IO
很明顯,我們的任務(wù)管理系統(tǒng)的真正很酷的應(yīng)用是web服務(wù)器。它有一個任務(wù)是在套接字上偵聽是否有新連接,當(dāng)有新連接要建立的時候 ,它創(chuàng)建一個新任務(wù)來處理新連接。
web服務(wù)器最難的部分通常是像讀數(shù)據(jù)這樣的套接字操作是阻塞的。例如PHP將等待到客戶端完成發(fā)送為止。對一個WEB服務(wù)器來說,這 根本不行;這就意味著服務(wù)器在一個時間點上只能處理一個連接。
解決方案是確保在真正對套接字讀寫之前該套接字已經(jīng)“準(zhǔn)備就緒”。為了查找哪個套接字已經(jīng)準(zhǔn)備好讀或者寫了,可以使用 流選擇函數(shù)。
首先,讓我們添加兩個新的 syscall,它們將等待直到指定 socket 準(zhǔn)備好:
復(fù)制代碼 代碼如下:<?php
function waitForRead($socket) {
return new SystemCall(
function(Task $task, Scheduler $scheduler) use ($socket) {
$scheduler->waitForRead($socket, $task);
}
);
}
function waitForWrite($socket) {
return new SystemCall(
function(Task $task, Scheduler $scheduler) use ($socket) {
$scheduler->waitForWrite($socket, $task);
}
);
}
這些 syscall 只是在調(diào)度器中代理其各自的方法: 復(fù)制代碼 代碼如下:
<?php
// resourceID => [socket, tasks]
protected $waitingForRead = [];
protected $waitingForWrite = [];
public function waitForRead($socket, Task $task) {
if (isset($this->waitingForRead[(int) $socket])) {
$this->waitingForRead[(int) $socket][1][] = $task;
} else {
$this->waitingForRead[(int) $socket] = [$socket, [$task]];
}
}
public function waitForWrite($socket, Task $task) {
if (isset($this->waitingForWrite[(int) $socket])) {
$this->waitingForWrite[(int) $socket][1][] = $task;
} else {
$this->waitingForWrite[(int) $socket] = [$socket, [$task]];
}
}
waitingForRead 及 waitingForWrite 屬性是兩個承載等待的socket 及等待它們的任務(wù)的數(shù)組。有趣的部分在于下面的方法,它將檢查 socket 是否可用,并重新安排各自任務(wù): 復(fù)制代碼 代碼如下:
<?php
protected function ioPoll($timeout) {
$rSocks = [];
foreach ($this->waitingForRead as list($socket)) {
$rSocks[] = $socket;
}
$wSocks = [];
foreach ($this->waitingForWrite as list($socket)) {
$wSocks[] = $socket;
}
$eSocks = []; // dummy
if (!stream_select($rSocks, $wSocks, $eSocks, $timeout)) {
return;
}
foreach ($rSocks as $socket) {
list(, $tasks) = $this->waitingForRead[(int) $socket];
unset($this->waitingForRead[(int) $socket]);
foreach ($tasks as $task) {
$this->schedule($task);
}
}
foreach ($wSocks as $socket) {
list(, $tasks) = $this->waitingForWrite[(int) $socket];
unset($this->waitingForWrite[(int) $socket]);
foreach ($tasks as $task) {
$this->schedule($task);
}
}
}
stream_select 函數(shù)接受承載讀取、寫入以及待檢查的socket的數(shù)組(我們無需考慮最后一類)。數(shù)組將按引用傳遞,函數(shù)只會保留那些狀態(tài)改變了的數(shù)組元素。我們可以遍歷這些數(shù)組,并重新安排與之相關(guān)的任務(wù)。
為了正常地執(zhí)行上面的輪詢動作,我們將在調(diào)度器里增加一個特殊的任務(wù): 復(fù)制代碼 代碼如下:
<?php
protected function ioPollTask() {
while (true) {
if ($this->taskQueue->isEmpty()) {
$this->ioPoll(null);
} else {
$this->ioPoll(0);
}
yield;
}
}
分享:php修改NetBeans默認(rèn)字體的大小在Netbeans中由于使用了Swing進行開發(fā),所以其中界面的字體也是由Java虛擬機進行配置而不是隨操作系統(tǒng)的。在安裝完Netbeans后默認(rèn)的字體大小是11px。而在Windows下的宋體最小支持12px。所以字體為11px就已經(jīng)無法完整顯示了。 簡單的解決辦法就是將字體改大一點。詳細的
- 相關(guān)鏈接:
- 教程說明:
PHP教程-PHP中使用協(xié)同程序?qū)崿F(xiàn)合作多任務(wù)第1/2頁(5)
。