首先介绍一下这个项目:这是我的毕业设计,一个B/S系统,用于ACM/ICPC(国际大学生程序设计竞赛)的再线评测与竞赛。
附加说明: 该项目将作为遵循 GPL协议 的开源项目发布。
评测过程是这样的,选手通过浏览器登陆系统,阅读编程问题描述(这里所有问题都有标准输入和输出),然后编写代码,通过标单提交,在服务器端对选手的代码进行检查,然后编译运行,服务器要对选手的程序运行状态进行控制,主要控制这几项:
编译错误(Compile Error)
运行时错误(Runtime Error)
使用内存超出限制(Memory Limit Exceeded)
消耗CPU时间超出限制(Time Limit Exceeded)
程序输出的信息量超出限制(Output Limit Exceeded)
出现以上任何一项问题都要立即中止评测,并给出错误报告,反馈给选手。
如果编译运行成功,则对程序输出的信息进行检查,此时有以下情况
程序输出与期望的相同(Accepted)
程序输出与期望的不同(Wrong Answer)
程序输出格式有误(Presentation Error)
对于以上三种情况要分别给出信息,反馈给选手。
在比赛中,会有10道以内的编程题供选手解答。
对于比赛成绩的判定实行罚时记分制,即比赛开始时所有选手分数为0,然后依选手提交代码并得到(Accept)的时间来进行扣分,即选手提交代码越晚,扣分越多,同时如果提交代码后得到Accept以外的任何结果,都进行相应的扣分。
比赛结束后,先按选手解题数目,然后按罚时排序,同样的解题数,罚时越小越靠前。
以上为整个系统的功能概况。我把这个系统分为三个部分来完成:
1。评测程序
2。数据库
3。用户界面
评测程序在整个系统中的地位是非常重要的,而且也是难度最高的,所以我将这一个模块的实现放到了首要位置。
以下是试验阶段的部分代码,使用父进程对待运行的客户程序进行监视,用wait4()函数来监控并取得子进程的终止状态,子进程调用客户程序,并使用setrlimit来限制它。
这样已经可以判断出各种运行时错误,准确计算运行时间,唯一的问题是内存不好测量
#include
<
stdio.h
>
#include
<
sys
/
resource.h
>
#include
<
sys
/
time.h
>
#include
<
signal.h
>
#include
<
unistd.h
>
#include
<
stdlib.h
>
#include
<
sys
/
wait.h
>
#include
<
errno.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
MEGA_BYTES 1048576
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[])
{
pid_t pid = vfork();
if( pid > 0){
struct rusage contest_usage;
int ret;
int contest_status;
do {
// non-block wait, so as to monitor the child proccess' status
ret = wait4(pid, &contest_status, WNOHANG, &contest_usage);
}while(ret == 0);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(WIFEXITED(contest_status)){
puts("hooray!"); // the child process terminated normally
}
else if(WIFSIGNALED(contest_status)){
printf("There might be some error! ");
int sig = WTERMSIG(contest_status);
printf("error id: %d ", sig);
if(sig == SIGXCPU){
puts("time limit exceeded");
}
if(sig == SIGXFSZ){
puts("output limit exceeded");
}
if(sig == SIGSEGV){
puts("runtime error");
}
if(sig==SIGKILL){
puts("memory limit exceeded");
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// calculate the time used by contestant's process
double utime,stime,tmp;
utime = contest_usage.ru_utime.tv_sec*1000.0 + contest_usage.ru_utime.tv_usec/1000.0;
stime = contest_usage.ru_stime.tv_sec*1000.0 + contest_usage.ru_stime.tv_usec/1000.0;
printf("user time: %f ",utime);
printf("sys time: %f ",stime);
// how to count the memory cost of the process?
//
}
else {
struct rlimit limit;
// forbid the system to do core dump;
// getrlimit(PLIMIT_CORE, &limit);
limit.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &limit);
// set the limit on the child process's CPU time
getrlimit(RLIMIT_CPU, &limit);
limit.rlim_cur = 3;
setrlimit(RLIMIT_CPU, &limit);
// set the limit on the child process's memory
getrlimit(RLIMIT_AS, &limit);
limit.rlim_cur = 128*MEGA_BYTES;
setrlimit(RLIMIT_AS, &limit);
// set the limit on the Maximum size of file created by child process
getrlimit(RLIMIT_FSIZE, &limit);
limit.rlim_cur = 1024; // currently set to 100K;
setrlimit(RLIMIT_FSIZE, &limit);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int exec_ret;
freopen("infile","r",stdin);
exec_ret = execv("./contestant.out", argv);
// if it goes here, there must be something wrong
printf("an exception! error id: %d ", exec_ret);
}
}
附加说明: 该项目将作为遵循 GPL协议 的开源项目发布。
评测过程是这样的,选手通过浏览器登陆系统,阅读编程问题描述(这里所有问题都有标准输入和输出),然后编写代码,通过标单提交,在服务器端对选手的代码进行检查,然后编译运行,服务器要对选手的程序运行状态进行控制,主要控制这几项:
编译错误(Compile Error)
运行时错误(Runtime Error)
使用内存超出限制(Memory Limit Exceeded)
消耗CPU时间超出限制(Time Limit Exceeded)
程序输出的信息量超出限制(Output Limit Exceeded)
出现以上任何一项问题都要立即中止评测,并给出错误报告,反馈给选手。
如果编译运行成功,则对程序输出的信息进行检查,此时有以下情况
程序输出与期望的相同(Accepted)
程序输出与期望的不同(Wrong Answer)
程序输出格式有误(Presentation Error)
对于以上三种情况要分别给出信息,反馈给选手。
在比赛中,会有10道以内的编程题供选手解答。
对于比赛成绩的判定实行罚时记分制,即比赛开始时所有选手分数为0,然后依选手提交代码并得到(Accept)的时间来进行扣分,即选手提交代码越晚,扣分越多,同时如果提交代码后得到Accept以外的任何结果,都进行相应的扣分。
比赛结束后,先按选手解题数目,然后按罚时排序,同样的解题数,罚时越小越靠前。
以上为整个系统的功能概况。我把这个系统分为三个部分来完成:
1。评测程序
2。数据库
3。用户界面
评测程序在整个系统中的地位是非常重要的,而且也是难度最高的,所以我将这一个模块的实现放到了首要位置。
以下是试验阶段的部分代码,使用父进程对待运行的客户程序进行监视,用wait4()函数来监控并取得子进程的终止状态,子进程调用客户程序,并使用setrlimit来限制它。
这样已经可以判断出各种运行时错误,准确计算运行时间,唯一的问题是内存不好测量
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)