OJ判题核心实现(获取时间消耗、空间消耗)wait4、vfork实现

本文介绍了如何在Linux环境下实现一个判题系统,重点在于利用vfork创建子进程,setrlimit设置资源限制,以及wait4获取程序的时间和内存消耗。通过这种方法,可以精确地监控程序的运行状态,避免因机器负载导致的误判。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判题需要几个步骤:

1.在linux搭建编译器环境:gcc g++ java python2 python3 pascal

2.根据源码的类型创建相应的源文件(.c .cpp .java 等)

3.编译对应的源文件

4.运行程序,使用测试用例测试得出时间消耗和内存消耗。

步骤中其实最难的就是第四步,怎么获得程序的时间消耗和空间消耗?有个思路:开线程运行该程序得到进程pid,然后主线程开个死循环不断通过这个pid,查出这个程序的内存消耗,比较保存一个最大的空间消耗值,轮训过程中判断运行时间是否超过规定时间,如果超过,那么kill该进程直接得出结果(TLE)。

这样求得的时间消耗其实不是很准的,比如说机器的其他计算任务很多,那么很多时间这个进程是处于就绪等待的状态,也就是没用CPU,什么都不做,这样的话,原本能跑过的程序我们也判为TLE了。获取进程的时间linux内核提供的有的,接下来会有演示怎么用。

判题流程:

 

核心命令:

  • vfork();创建子进程
  • setrlimit(RLIMIT_CPU, &rl);设置子进程的时间、内存限制
  • execvp(args[0],args);运行可执行程序
  • wait4(pid, &status, 0, &ru);回收子进程
  • 判别子进程退出的类别(超时或者超内存)

第一步:vfork一个进程出来用于运行这个可执行程序

demo:创建一个子进程,获得pid

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
int main()
{
    int pid = vfork();
    if(pid < 0)
        printf("error in fork!\n");
    else if (pid == 0) {
        printf("this is child, pid is %d\n", getpid());
        int newstdin = open(in,O_RDWR|O_CREAT,0644);
        int newstdout=open(out,O_RDWR|O_CREAT,0644);
        dup2(newstdout,fileno(stdout));
        dup2(newstdin,fileno(stdin));
        exit(0);
    }else if (pid > 0) {
        printf("this is parent, pid is %d\n", getpid());
    }
    return 0;
}

第二步:重定向标准控制台IO到测试用例输入文件、结果输出文件


                
BNUEP Offline Judge 北京师范大学珠海分校离线评测系统是在具备目测试数据的情况下,能无联网自动评测ACM/ICPC模式的源代码评测系统(即本地测试工具、评测机)。它主要有以下功能(所有的功能都无需联网,在本机即可实现): *评测核心功能: 基本具备Online Judge的核心功能,如编译代码、内存限定,时间限定,获取代码长度等; *支持多种语言: 1.0 Beta2版本支持C/C++、Pascal、C#、JAVA; *出模式 可以在有标准输入数据和标准程序的情况下,由系统产生标准输出数据,并可批量保存,同时自动命名标准输出数据的后缀; *文本高亮对比 在后,可以直接在本系统中将自己的程序输出和标准输出进行高亮的文本差异对比,操作类似于一些文本对比软件,在一定程度上可以较方便地发现WA代码的出错细节; *支持不限时执行代码 这个功能可以在一定程度上检测TLE代码的算法是否正确的,当然,不能是跑一天都没跑出来的程序; *打包与加密测试数据 使用加密后的数据可以正常,但不显示标准输出。这个功能是为了弥补放出去给别人评测的测试数据是明文的缺陷。加密之后评测方就看不到测试数据。这样就既可以实现离线评测,又可以实现Online Judge上的对测试数据屏蔽; ACM-ICPC简介: ACM国际大学生程序设计竞赛(简称ACM-ICPC)是由国际计算机界具有悠久历史的权威性组织ACM学会(Association for Computing Machinery)主办,是世界上公认的规模最大、水平最高、参与人数最多的大学生程序设计竞赛,其宗旨是使大学生能通过计算机充分展示自己分析问和解决问的能力。 ACM-ICPC的每一道,都具备目、需求描述、输入格式描述、输出格式描述、样例输入和样例输出共六大信息,有些目还有一定的提示。此外,裁还额外存储了关于该的一组或多组对选手屏蔽的标准输入和标准输出数据,这些测试数据已经经过验证符合意要求。当用户提交一道目的源码之后,裁会将该源码放入评测系统中编译运行,并使用标准输入作为用户程序的输入,然后获取用户程序的输出,接着,将用户程序输出和标准输出比较,最后返回给用户一个评结果。评结果包括:Accepted(测试通过)、Compile Error(编译失败)、Memory Limit Exceed(内存超出限制)、Presentation Error(格式错误)、Runtime Error(运行时错误,可能是数组越界,改写只读的内存,除零,栈或堆溢出等错误)、Time Limit Exceed(时间超出限制)、Wrong Answer(答案错误)等。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值