程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP CLI模式下的多進程應用

PHP CLI模式下的多進程應用

編輯:關於PHP編程

       PHP在很多時候不適合做常駐的SHELl進程, 他沒有專門的gc例程, 也沒有有效的內存管理途徑. 所以如果用PHP做常駐SHELL, 你會經常被內存耗盡導致abort而unhappy.

      而且, 如果輸入數據非法, 而腳本沒有檢測, 導致abort, 也會讓你很不開心.

      那? 怎麼辦呢?

      呵呵, 別著急, 多進程來幫您!

      那,這是為什麼呢?

      優點:

      1. 使用多進程, 子進程結束以後, 內核會負責回收資源

      2. 使用多進程,子進程異常退出不會導致整個進程Thread退出. 父進程還有機會重建流程.

      3. 一個常駐主進程, 只負責任務分發, 邏輯更清楚.

      Then, 怎麼做呢?

      接下來, 我們使用PHP提供的POSIX和Pcntl系列函數, 來實現一個PHP命令解析器, 主進程負責接受用戶輸入, 然後fork子進程執行, 並負責回顯子進程的結束狀態.

      代碼如下, 我加了注釋, 如果有不懂的地方, 可以翻閱手冊相關函數, 或者回復留言.

      #!/bin/env php

      /** A example denoted muti-process application in php

      * @filename fork.php

      * @touch date Wed 10 Jun 2009 10:25:51 PM CST

      * @author Laruence

      * @license http://www.zend.com/license/3_0.txt   PHP License 3.0

      * @version 1.0.0

      */

      /** 確保這個函數只能運行在SHELL中 */

      if

      (substr(php_sapi_name(), 0, 3) !== 'cli')

      {

      die("This Programe can only be run in CLI mode");

      }

      /**  關閉最大執行事件限制, 在CLI模式下, 這個語句其實不必要 */

      set_time_limit(0);

      $pid  = posix_getpid(); //取得主進程ID

      $user = posix_getlogin(); //取得用戶名

      echo

      <<

      USAGE: [command | expression]

      input php code to execute by fork a new process

      input quit to exit

      Shell Executor version 1.0.0 by laruence

      EOD;

      while

      (true)

      {

      $prompt = "n{$user}$ ";

      $input  = readline($prompt);

      readline_add_history($input);

      if

      ($input == 'quit')

      {

      break;

      }

      process_execute($input . ';');

      }

      exit(0);

      function

      process_execute($input)

      {

      $pid = pcntl_fork(); //創建子進程

      if

      ($pid == 0)

      {//子進程

      $pid = posix_getpid();

      echo

      "* Process {$pid} was created, and Executed:nn";

      eval($input); //解析命令

      exit;

      }

      else

      {//主進程

      $pid = pcntl_wait($status, WUNTRACED); //取得子進程結束狀態

      if

      (pcntl_wifexited($status))

      {

      echo

      "nn* Sub process: {$return['pid']} exited with {$status}";

      }

      }

      }

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved