在線測評系統開發日誌1
在線測評系統開發日誌
早在四年前常老師爲了解決信息學競賽做題評測不方便的問題,決定開發一套C/S標準版的基於Windows2000+IIS5+ASP的在線評測系統(不知 道什麼叫在線評測系統?好吧,例如Vijos,USACO)。經過長期的開發計劃的擬定,終於開始編寫程序。但事情並不順利,常老師很快就遇到了一個棘手 的問題:如何把超時程序的進程殺掉。其實按道理說調用pskill命令應該能結束進程,但是在IIS中,ASP調用的進程是運行在Pool中的,所以被 Windows保護着,pskill是殺不死的。於是問題便被擱置了半年之久。
---------------------------------------CmYkRgB123的分割線------------------------------------------- 後來,熟悉Linux的葉老師來到河南省實驗中學。一次偶然的機會常老師問葉老師能否在Linux下殺掉進程,葉老師經過試驗證明是可以的,於是常老師和 葉老師又繼續開發。緊接着又遇到一個問題,Linux+Apache不支持ASP。可是常老師想出瞭解決辦法,把頁面留在Windows服務器,評測系統 在Linux下運行,用FTP傳輸測試數據。但沒有ASP支持的Linux有個嚴重的問題,無法接受來自Windows的信息。這也就意味着程序和數據被 FTP過來後無法被識別是哪個用戶提交的,所以只好通過提交的文件名來區分用戶。於是後來的半成品中就出現了這種怪象"輸入文件名改爲 00002E51.in輸出文件名改爲000002E51.out"。 在Linux下,評測器的工作原理是這樣的:實時監視/home/tester/src目錄文件動向,一旦出現了被FTP過來的測試數據 和*.pas文件,立刻調用編譯器,然後執行程序,檢查結果並與測試數據答案比較,返回Windows服務器信息。通過改文件名,理論上實現了多用戶同時 提交保證不混亂,經初步實踐也沒有什麼不妥,於是便投入使用。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 系統起初試用效果還可以,但BUG不會在它發生之前自動現身的。前年的NOI前夕,常老師指導羅牛等人研究討論IOI試題,而且使用該系統評測。這時候問 題出現了,交上去題後沒反應了。常老師只好去檢查怎麼回事。好不容易纔發現原來是測試數據還沒傳完(IOI很多題測試數據中一個竟然測試點200多 MB),幾百MB的東西反覆用FTP傳送極其緩慢。失望的常老師放棄了修正,於是開發進度永遠停留在了80%。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 2007年深秋的一個夜晚,我去找常老師問一道題。問完題順便和常老師聊一聊,就是那個時候常老師告訴了我上文的評測系統開發史。我深感惋惜,但惋惜是沒有用的,重要的是去改變它。於是我便開始思考重新締造一個系統。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 我深深的對ASP失望了:只能用VBS和JS兩種面向過程的腳本語言,執行效率低下,安全漏洞衆多。取而代之的是PHP。PHP是完全面向對象的語 言,標準函數衆多,支持廣泛,跨平臺,於是我選擇了它。最初我選擇在Windows2000+IIS5+MS SQL Server2000的環境下開發,但是在還沒開發之前我就否定了這種想法,還是殺進程的難題。所以我用了Apache代替IIS。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 先用PHP寫了一段代碼試試
代碼:
<?php
$timeout=1; //設定時限爲1秒
$process = proc_open("c:/a.exe", $descriptorspec, $pipes);//a.exe是一個死循環程序
$time_start = getmicrotime(); //獲取開始時間
do{
$status=proc_get_status($process);//獲取進程狀態
if (!$status['running']) break; //如果已經運行完就結束
$time_now = getmicrotime();$rtime=$time_now-$time_start; //計算程序已執行時間
if ($rtime>$timeout) proc_terminate($process); //如果超時就殺死進程
} while (true);
?>
恩, 還不錯,頁面成功完成了。可是電腦爲什麼突然變得這麼慢?打開任務管理器,發現CPU佔用100%,原來a.exe(PID 1645)還在運行(暈倒死)。我不是已經殺了嗎?頁面也返回正常的信息。於是我準備手工殺掉他,這時候蹦出個對話框,上面赫然寫着“拒絕訪問!”(吐 血)。我只好使用我的絕招ntsd -c q -p 1645,成功殺掉進程。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 後來我才知道,原來在Windows下網頁程序只能在Pool中執行,也就是說無論是IIS還是Apache調用的程序都會被保護起來,殺不掉的。調用ntsd是個方法,但是容易引起Apache或IIS崩潰。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 徹底對Windows失去信心,轉戰Linux。配置Linux + Apache2.24 + PHP 5.2.3 + Mysql5.0.45費了我好大功夫。不過還好不錯,能用了。
2008-1-10 14:03
再次執行那個頁面,一切OK,進程完美地被殺掉了。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 正式開始寫程序,首先寫成一個簡單的核心部件,確保能用在系統編寫。大概流程是這樣的: 在Mysql數據庫中建立兩個表userinfo和result分別存儲帳號信息和測評結果 index.php提供登錄界面 submit.php提供提交界面,支持pascal c c++三種語言 upload.php進行編譯和測評,輸出結果並寫入數據庫 result.php查詢測評結果 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 經過一個星期的努力,終於初步完成了設計。昨晚讓同學使用,效果還不錯。 成績查詢 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 至此不過是僅僅完成了可行性論證,真正的工作開沒有開始。這個系統相信還BUG多多,不過我還是感謝所有支持我的人特別是常老師。 ---------------------------------------CmYkRgB123的分割線------------------------------------------- 我把代碼發上來,懂PHP的可以看看,懇求您的指導。