程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> windows下解決PHP調用的外部程序超時阻塞問題

windows下解決PHP調用的外部程序超時阻塞問題

編輯:PHP綜合

我近期做一個東東,大致構架是:

訪問者通過web提交c程序,服務端調用編譯器編譯並且在編譯完成後運行編譯後的程序,將運行結果傳回訪問者浏覽器。

且不考慮安全性,因為訪問者可以都認為是可以信賴的,命令行編譯器最終要返回的,但是對於臨時編譯的程序,盡管用戶是可以信賴的,但是不排除因為不完善而出現死鎖,php調用後啟動的進程無法返回而超時,此進程一直存在直到服務器重啟,久而久之,服務器端資源就要耗盡。

考慮到php本身執行的時候沒有提供多線程和進程管理功能(可能是我沒有看到這方面的資料),使用不管是exec,還是popen等,主程序一旦阻塞就無法自拔,所以必須預留一個線程在必要時管理啟動的進程.而我又不想對服務器配置做改動。於是想到自己寫一個程序管理啟動的進程,php間接通過這個程序調用編譯後的客戶程序,實現對客戶程序超時的控制。

下面是測試用的php程序。

<?
 //filename:  test1.php
 $cmd="test.exe  24  154";//  input  you  command  here

 $cmd="process.exe  5000  ".$cmd;
 $descriptorspec  =  array(
    0  =>  array("pipe",  "r"),   //  stdin  is  a  pipe  that  the  child  will  read  from
    1  =>  array("pipe",  "w"),   //  stdout  is  a  pipe  that  the  child  will  write  to
    2  =>  array("file",  "error-output.txt",  "w+"),  //  stderr  is  a  file  to  write  to
 );
 $process  =  proc_open($cmd,  $descriptorspec,  $pipes);
 if  (is_resource($process))  {
     //  $pipes  now  looks  like  this:
     //  0  =>  writeable  handle  connected  to  child  stdin
     //  1  =>  readable  handle  connected  to  child  stdout
     //  Any  error  output  will  be  appended  to  /tmp/error-output.txt

     fwrite($pipes[0],  '12345678');//  input  integer  to  scanf,  you  should  add  '\n'  at  the  end  of  string  as  'Enter';

 fclose($pipes[0]);

     while(!feof($pipes[1]))  {
         echo  nl2br(fgets($pipes[1],  1024));
     }
     fclose($pipes[1]);
     //  It  is  important  that  you  close  any  pipes  before  calling
     //  proc_close  in  order  to  avoid  a  deadlock
 //proc_terminate($process);
     $return_value  =  proc_close($process);

     echo  "<br>command  returned  $return_value\n";
 }
 ?>

process.exe就是我編寫提供給php的代理程序。

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