OJ系统判题思路与代码实现

                                  OJ系统判题思路与代码实现

毕业设计做了个OJ系统,做得不好,打算重做,因为比较感兴趣,涉及到了许多东西,做系统的同时又把我在学校里学的东西给捡了回来,哈哈。

OJ系统判题思路与代码实现_第1张图片

输入:

exeFile:源程序文件

codeType:代码类型

test.in:输入文件

test.out:输出文件

timeLimit:时间限制

memoryLimit:内存限制

输出:

exitValue:子进程运行结果状态码

runTime:子进程运行时间

runMemory:子进程运行内存

 

 

一些相关说明:

  1. 主进程:调控子进程的程序。
  2. 子进程:执行源程序。
  3. 管道:(有名管道)子进程输出数据到管道中,主进程得以读取,

半双工式环形缓冲区,半双工地读写决定了父/子只能有一个进程读/写,所以父子进程轮流阻塞。

听说,有名管道环形缓冲,待验证,待审查对程序影响力。)

  1. fork()创建子进程
  2. setProcessLimit()自定义设定子进程资源限制函数,

包装修饰了setrlimit()库函数。

  1. 捕获Linux进程信号量(略)
  2. 获取进程PCB控制块信息(运行时间,内存...)

wait4(...)函数,PCB进程信息存在于调用wait4(...)函数传如的某个结构体引用中。

系统库结构体:struct rusage ru;
(运行时间)runTime = ru.ru_utime.tv_sec * 1000
           + ru.ru_utime.tv_usec / 1000
           + ru.ru_stime.tv_sec * 1000
           + ru.ru_stime.tv_usec / 1000;
(运行内存)runMemory = ru.ru_maxrss;

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define FIFO "stdout_fifo"
using namespace std;
typedef long long ll;
void setProcessLimit(const int& timeLimit, const ll& memoryLimit);
void runC_Code(const string& runFilePath);
void runC_cppCode(const string& runFilePath);
void runGoCode(const string& runFilePath);
void runJavaCode(const string& runFilePath);
void runPython3Code(const string& runFilePath);
/*
@Param:
args[0]: ./runCode
args[1]: timeLimit
args[2]: memoryLimit
args[3]: codeType
args[4]: runFilePath
args[5]: test.in
args[6]: test.out
@Result:
-1: 未知错误
32: AC
33: WA
34: TL
35: ML
36: RE
99: OE
*/
int main(int argc, char *args[]) {
    int timeLimit = atoi(args[1]);
    long memoryLimit = atol(args[2]);
    string codeType = args[3];
    string runFilePath = args[4];
    string inputFilePath = args[5];
    string outputFilePath = args[6];
    memoryLimit <<= 20;
    unlink(FIFO);
    int res = mkfifo(FIFO, 0777);
    pid_t pid = fork();
    if(pid < 0) {
        cerr << "fork失败" << endl;
        return -1;
    } else if(pid == 0) {
        freopen(inputFilePath.c_str(), "r", stdin);
        freopen("/test.error", "w", stderr);
        int fd = open(FIFO, O_WRONLY);
        dup2(fd, 1);
        setProcessLimit(timeLimit, memoryLimit);
        if(codeType == "c") {
            runC_Code(runFilePath);
        } else if(codeType == "c/c++") {
            runC_cppCode(runFilePath);
        } else if(codeType == "go") {
            runGoCode(runFilePath);
        }  else if(codeType == "java") {
            runJavaCode(runFilePath);
        } else if(codeType == "python3"){
            runPython3Code(runFilePath);
        }
    } else {
        FILE *output = fopen(outputFilePath.c_str(), "r");
        char buf[BUFSIZ], buf2[BUFSIZ];
        int fd = open(FIFO, O_RDONLY);
        int len = 0;
        int accept = 1;
        while((len = read(fd, buf, BUFSIZ)) != 0) {
            int len2 = fread(buf2, sizeof(char), len, output);
            if(len != len2) {
                accept = 0;
                break;
            } else {
                for(int i = 0; i < len; i++) {
                    if(buf[i] ^ buf2[i]) {
                        accept = 0;
                        break;
                    }
                }
                if(accept == 0) {
                    break;
                }
            }
        }
        fgetc(output);
        accept?(accept=feof(output)): kill(pid, SIGKILL);
        fclose(output);
        int status, runTime;
        long runMemory;
        struct rusage ru;
        wait4(pid, &status, WUNTRACED, &ru);
        runTime = ru.ru_utime.tv_sec * 1000
                   + ru.ru_utime.tv_usec / 1000
                   + ru.ru_stime.tv_sec * 1000
                   + ru.ru_stime.tv_usec / 1000;
        runMemory = ru.ru_maxrss;
        int result = -1;
        if(accept == 0) {
            //cout << "result:WA\n" < memoryLimit) {
                   //cout << "result:ML" << endl;
                   result = 35;
               } else {
                   //cout << "result:" << Signal[status2][0] << endl;
                   //cout << "message:" << Signal[status2][1] << endl;
                   result = 99;
               }
            }
        }
        cout << "runTime:" << runTime <> 1)) << 10;
    rl.rlim_max = (memoryLimit << 1) << 10;
    setrlimit(RLIMIT_DATA, &rl);
}
void runC_Code(const string& runFilePath) {
    if(access(runFilePath.c_str(), F_OK) == -1) {
        cerr << runFilePath << "没有找到" <

 

OJ系统判题思路与代码实现_第2张图片

你可能感兴趣的:(OJ,OJ,fork,判题,管道)