在线测评系统开发日志1

This post is written in Chinese. Please consider using Google Translate

在线测评系统开发日志

早在四年前常老师为了解决信息学竞赛做题评测不方便的问题,决定开发一套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的可以看看,恳求您的指导。

Related posts