1. 引言
ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest (ICPC))是由美国计算机协会(ACM)主办的一项旨在展示大学生编写程序、分析和解决问题能力的年度竞赛 [1] [2] 。在线评测系统起源于ICPC中用来自动评判参赛选手成绩的ACM评测系统,其评判原理是基于黑盒测试。在线评测系统对于培养学生编程兴趣、提高学生编程能力具有重要意义,目前国内较著名的在线评测系统如北京大学的POJ、浙江大学的ZOJ等。
本系统 [3] - [9] 采用B/S架构下Web程序应用平台中主流的LAMP模式 [10] [11] [12] [13] [14] 进行开发,即选用Linux系统,使用Apache搭建服务器,前端使用PHP语言编写,数据库使用体积小、速度快、成本低、灵活性高的MySQL。
2. 系统设计
2.1. 系统架构
为了满足程序系统的需求,进行灵活的判题分析,系统采用B/S架构。架构图如图1所示。具体分析该系统,将其设计为如下四个组成部分:
1) 网站系统(Web端):Web端与普通系统相同,解决用户管理、题库管理、提交代码和统计分析等基本功能。
2) 判题核心(Judge):和判题守护进程相互配合,一旦判题队列中出现了用户提交的代码,就对这段代码进行编译、运行,并对运行下来的结果与样式输出进行比较,将结果存入数据库。需要修建围墙来
保证系统的安全性,不能够接受恶意代码。
3) 封装层(Judge Wrapper):这一层是Web端与判题内核互通的一个桥梁,它负责调用Judge层来完成Web端的响应,这使得判题核心成为一个独立的功能模块。此外,可以屏蔽掉Web端带来的一些恶意代码的危害,将一些潜在的威胁在进入到核心判题层之前先打退回去,确保系统安全平稳运行。
4) 侦听守护进程(Daemon):守护程序是一个基于多线程的TCP服务,始终轮询数据库的solution表是否有新的记录出现,若有,则调用封装层,并由封装层对核心判题层进行调用。
系统将采用LAMP的模式,如图2所示,客户访问架设在Apache服务器上的Web前端,服务器会读取目录下存放的.html和.php文件,并使用PHP连接MySQL,通过标准SQL语句操作存储网站内容的数据库反馈给用户。
2.2. 功能设计
整个系统划分为六个功能模块,即用户管理模块、题库管理模块、答题模块、判题模块、统计分析模块和算法教育模块。整个系统的功能结构图3所示。
2.3. 数据库设计
数据库中设计了用户表、题目表、状态表、源代码表和编译表5张表,建库后数据库关系图如图4所示。
3. 判题模块设计
3.1. 判题模块构成
判题模块由两部分组成:
judged(judge daemon):是一个守护进程,负责隔一段时间查找一下数据库中solution表是否存在新的用户提交的代码,若有,则加入判题队列。当有新的任务时开启judge client进程。judged流程图如图5所示。
Judge_client是核心的判题程序,担负着编译、运行和监测的工作,是系统的核心功能模块,也是最容易出现问题导致系统不能正常运行的一个模块。Judge_client流程图如图6所示。
3.2. 关键技术
3.2.1. 轮询
用于判题守护进程中响应用户的答案提交行为,判题守护进程隔一段时间检查solution表中是否有新增数据,若有,则生成一个子进程来编译用户的代码,这些子进程形成一个任务队列,由判题内核依次执行。
3.2.2. 管道
用于进程间的通信,在指定文件夹下保存一份用户提交的代码,视情况而定调用不同编译器并利用exec族函数执行文件可以达到目的,编译时由父进程监视子进程的执行,若执行完,则在队列中执行下一个子进程。在结果对比中,判题程序每次从管道中读取一个字符,并与样式输出进行比对,直到匹配结束,一致则说明结果正确。
3.2.3. 安全性相关
为了避免用户提交的恶意代码对判题机产生危害,需要从几个方面对用户代码生成程序加以限制。
1) 输入输出
由于禁止用户程序开启文件,需要通过freopen函数重定向输入输出流,主要指用户程序stdin(标准输入)、stdout(标准输出)、stderr(标准错误输出)三个流。
2) 权限
通过setuid系统调用限制用户进程的权限(设置为持有最低权限的用户ID,本系统采用了nobody这个操作系统内置的、权限最低的用户)。在资源限制方面,进程的时间、内存、栈空间和输出文件大小都需要受到限制。这些资源限制通过setrlimit和setitimer等系统调用结合来完成。
3) 运行时检测
使用ptrace函数,主要监测以下几点:① 监测程序是否安全退出。② 监测程序是否收到了如SIGALRM、SIGVTALRM、SIGXCPU、SIGXFSZ、SIGSEGV、SIGFPE、SIGBUS、SIGABRT等异常信号。③ 监测资源是否超出了最大限度。④ 监测是否合法地进行了系统的调用。若任一项出现问题,一定是因为子进程的某些错误所致,必须即刻终止子进程。
4. 系统展示
4.1. 界面展示
篇幅所限,这里只给出系统部分运行截图(如图7~10)。
4.2. 功能测试
对系统功能制定了严格的测试计划,编写了完备的测试用例表对系统进行功能测试,并在测试的基础上进行修改,重新测试,最终所有功能模块均能满足期望目标。
5. 结束语
本文设计并实现了一个基于LAMP架构的在线评测系统,提供了一个开放的自动判题的平台,通过网络技术,帮助学校更快更好地完成程序设计选拔和日常训练工作。
基金项目
南京中医药大学教师教学发展专项课题(编号:nzyjsfz-201620)。