我近期做一個東東,大致構架是:
訪問者通過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的代理程序。