PHP中使用協同程序實現合作多任務(5)_PHP教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:php修改NetBeans默認字體的大小
      在Netbeans中由于使用了Swing進行開發,所以其中界面的字體也是由Java虛擬機進行配置而不是隨操作系統的。在安裝完Netbeans后默認的字體大小是11px。而在Windows下的宋體最小支持12px。所以字體為11px就已經無法完整顯示了。 簡單的解決辦法就是將字體改大一點。詳細的

      這段代碼將打印以下信息:

      復制代碼 代碼如下:
      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.

      經過三次迭代以后子任務將被殺死,因此這就是"Child is still alive"消息結束的時候。可能應當指出的是這不是真正的父子關系。 因為甚至在父任務結束后子任務仍然可以運行。或者子任務可以殺死父任務。可以修改調度器使它具有更層級化的任務結構,不過 在這篇文章里我沒有這么做。 

      你可以實現許多進程管理調用。例如 wait(它一直等待到任務結束運行時),exec(它替代當前任務)和fork(它創建一個 當前任務的克隆)。fork非常酷,而且你可以使用PHP的協程真正地實現它,因為它們都支持克隆。 

      然而讓我們把這些留給有興趣的讀者吧,我們去看下一個議題。

      幾點人
      翻譯于 4天前
      0人頂
      頂 翻譯的不錯哦!
       

      非阻塞IO
      很明顯,我們的任務管理系統的真正很酷的應用是web服務器。它有一個任務是在套接字上偵聽是否有新連接,當有新連接要建立的時候  ,它創建一個新任務來處理新連接。
       web服務器最難的部分通常是像讀數據這樣的套接字操作是阻塞的。例如PHP將等待到客戶端完成發送為止。對一個WEB服務器來說,這 根本不行;這就意味著服務器在一個時間點上只能處理一個連接。

      解決方案是確保在真正對套接字讀寫之前該套接字已經“準備就緒”。為了查找哪個套接字已經準備好讀或者寫了,可以使用 流選擇函數。 

      首先,讓我們添加兩個新的 syscall,它們將等待直到指定 socket 準備好:

      復制代碼 代碼如下:
       <?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 只是在調度器中代理其各自的方法:  復制代碼 代碼如下:
       <?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 及等待它們的任務的數組。有趣的部分在于下面的方法,它將檢查 socket 是否可用,并重新安排各自任務: 復制代碼 代碼如下:
       <?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 函數接受承載讀取、寫入以及待檢查的socket的數組(我們無需考慮最后一類)。數組將按引用傳遞,函數只會保留那些狀態改變了的數組元素。我們可以遍歷這些數組,并重新安排與之相關的任務。

      為了正常地執行上面的輪詢動作,我們將在調度器里增加一個特殊的任務: 復制代碼 代碼如下:
       <?php 
       protected function ioPollTask() { 
           while (true) { 
               if ($this->taskQueue->isEmpty()) { 
                   $this->ioPoll(null); 
               } else { 
                   $this->ioPoll(0); 
               } 
               yield; 
           } 
       }
       

      分享:PHP刪除數組中特定元素的兩種方法
      這篇文章介紹了PHP中刪除數組中特定元素的兩種方法,有需要的朋友可以參考一下 方法一: 復制代碼 代碼如下: ?php $arr1 = array(1,3, 5,7,8); $key = array_search(3, $arr1); if ($key !== false) array_splice($arr1, $key, 1); var_dump($arr1); ? 輸出: array(4)

      來源:模板無憂//所屬分類:PHP教程/更新時間:2013-07-03
      相關PHP教程