Golang Go语言中如何实现一个 OJ 的评测机?
Golang Go语言中如何实现一个 OJ 的评测机?
在做一个 OJ 系统的评测机,需要做一个容器隔离用户程序,并且监控程序使用到的内存大小和时间
别人推荐使用 cgroup 以及 clone 、ubshare 的系统调用,可是找不到相关资料
大家有什么方法推荐吗?
我有一个方法。。。上 github 借鉴借鉴。。。
更多关于Golang Go语言中如何实现一个 OJ 的评测机?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
uoj 的做法好像是 docker
做的第一个项目就是和同学一起搞了个 oj,评测机直接拉一个 docker 起来跑完删掉。。。我记得这个方案的缺陷是无法区分内存爆掉和超时的情况?
代码完全读不懂
那也得硬读。。。我想应该不会有资料一步一步教怎么做一个评测机
去搜搜本科论文库,有不少 CS 的哥们本科毕业设计做的这个
以前的一个面试官写的,并且用在他们学校的校赛上了,你可以参考一下,整体不难,一个调度中心,一堆 worker https://github.com/ma6174/acmjudger
如果想了解一下简单的判题原理的话可以看看我的博客文章 https://www.lanrongqi.com/2020/08/online-judge-development-2 ,这个是我自己用的 go 写的判题机 https://github.com/LanceLRQ/deer-executor , 不过没有实现沙箱功能,生产环境是直接放 docker 里跑的。也没用到 cgroup 那些,在学了在学了…╮( ̄▽ ̄)╭
顺便给你个我虽然没用过但是看源代码感觉还蛮厉害的 go 语言判题机 https://github.com/criyle/go-judge
一起学习交流呀
考虑下用 Docker 吧,如果有人乱搞得考虑 OJ 被黑掉的场合
#3 +1
单纯的 docker 不一定安全,gvisor 应该更靠谱些。
印象还有超轻虚拟机+docker 方案。
就是这个源码我看不懂,配上作者的博客也无法理解
非主流方法:如果评测机用的是 Ubuntu 等自带 AppArmor 的系统的话,倒是可以不用容器,通过 AppArmor 来实现安全加固。
内存和时间限制,一般来说是联用轮询和 rlimit 系统资源限制:
1 )定时器限制时间+轮询采样内存消耗情况作为主要监控手段,用于反馈 TLE/MLE
2 ) rlimit 系统限制设得比题面描述高一些,用来保底
(不单用 rlimit 是因为超限程序会被直接杀死,从而无法区分 RE, TLE 和 MLE ;而且无法限制程序的非用户态时间)
另外,安全方面还有 ptrace, seccomp 等传统方法。
嗯,我再试试
在Golang中实现一个OJ(在线评测系统)的评测机,主要涉及到以下几个关键步骤:
-
输入/输出处理: 评测机需要能读取用户提交的代码的输入,并将代码的输出与预期结果进行比较。可以使用标准输入/输出来实现,例如通过
os/exec
包执行代码并捕获其输出。 -
沙箱执行: 为了防止恶意代码对系统造成危害,需要在沙箱环境中执行用户代码。可以使用容器技术(如Docker)或操作系统级别的权限隔离来实现。
-
时间/内存限制: 评测机需要能够监控并限制代码执行的时间和内存使用。可以使用
context
包来设置执行超时,并通过监控进程的资源使用情况来实现内存限制。 -
编译与执行: 根据提交的代码语言,调用相应的编译器或解释器进行编译和执行。例如,对于Go语言代码,可以直接使用
go run
命令。 -
结果判定: 将用户代码的输出与预期结果进行比较,判定其正确性。可以使用字符串匹配、正则表达式或专门的比较函数来实现。
-
日志与错误处理: 记录代码执行过程中的日志和错误信息,以便在代码执行失败时进行调试和分析。
综上所述,实现一个OJ评测机需要综合考虑输入/输出处理、沙箱执行、时间/内存限制、编译与执行、结果判定以及日志与错误处理等多个方面。通过合理的设计和实现,可以确保评测机的安全性和准确性。