负载均衡式在线OJ---------第二幕

发布时间:2026/8/14 15:12:43

负载均衡式在线OJ---------第二幕
个人主页:小则又沐风个人专栏:数据结构竞赛专栏C语言CLinuxOJ项目目录前言代码与运行模块代码思路管理资源分配上限合并代码(编译和运行--引入json库)删除临时文件前言我们目前的项目知识简单的实现了代码的编译的功能,显而易见的是我们还需要代码的运行的功能.今天我们的任务就是来实现一下项目中的代码运行的模块代码与运行模块在实现这个模块之前我们需要建立起来一个共识:首先我们将用户提交的代码运行我们关心的是什么???我们这个模块并不是关心用户的代码运行是否正确.我们关心的是用户的代码是否能够运行起来.所以我们关心的就是代码运行的错误或者是正常.至于代码运行的结果是否正确就是项目的另外的模块了.(需要对运行结果和我们提供的测试用例进行比对)在确定我们运行模块的主要任务之后我们现在来编写一下我们的代码代码思路我们实现这个模块的思路还是通过创建子进程进行进程替换来完成的.代码运行的我们需要知道的是代码运行的输出结果是什么,需要知道如果代码运行出错的话错误的原因是什么.当然成熟的项目也需要提供给用户一个自测的功能.也就是需要提供一个输入的接口所以我们需要产生三个文件#pragma once #include iostream #include string #include stdio.h #include unistd.h #include fcntl.h #include unistd.h #include sys/stat.h #include sys/wait.h #include ../comm/util.hpp #include ../comm/Log.hpp using namespace LogMoudle; using namespace util; class ns_run { public: ns_run() { } ~ns_run() { } public: static int Run(const std::string file_name) { std::string std_in PathUtil::StdIn(file_name); std::string std_out PathUtil::StdOut(file_name); std::string std_error PathUtil::StdError(file_name); std::string _excute PathUtil::Exe(file_name); umask(0); int std_infd open(std_in.c_str(), O_CREAT | O_RDONLY, 0644); int std_outfd open(std_out.c_str(), O_CREAT | O_WRONLY, 0644); int std_errorfd open(std_error.c_str(), O_CREAT | O_WRONLY, 0644); int fd fork(); if (fd 0) { LOG(LogLevel::ERROR) fork error; close(std_infd); close(std_outfd); close(std_errorfd); return -1; } else if (fd 0) { dup2(std_infd, 0); dup2(std_outfd, 1); dup2(std_errorfd, 2); execl(_excute.c_str(), _excute.c_str(), nullptr); LOG(LogLevel::ERROR) execl error; exit(1); } else { int status; close(std_infd); close(std_outfd); close(std_errorfd); waitpid(fd, status, 0); LOG(LogLevel::INFO) 运行完毕 : (status 0x7F); return status 0x7f; } } };现在我们来测试一下我们的代码#includeiostream using namespace std; int main() { couthelloendl; return 0; }#include compile.hpp #includerun.hpp int main() { Compile::my_compile(code); int nns_run::Run(code); return 0; }管理资源分配上限现在我们的代码是可以做到对用户提供的代码进行编译和运行的,但是现在有一个问题就是如果有恶意的代码想要占用我们cpu的资源的代码我们的程序也会运行这个代码.在我们使用成熟的OJ的时候我们会遇到代码超时和内存超出的问题,我们也需要类似的机制来保护我们的程序,所以我们需要对用户的代码进行时间和内存分配进行限制static void SetProcLimit(int _cpu_limit, int _mem_limit) { // cpu 限制 struct rlimit cpu_rlimit; cpu_rlimit.rlim_cur _cpu_limit; cpu_rlimit.rlim_max RLIM_INFINITY; setrlimit(RLIMIT_CPU, cpu_rlimit); // 内存限制单位是kb struct rlimit mem_rlimit; mem_rlimit.rlim_max RLIM_INFINITY; mem_rlimit.rlim_cur _mem_limit * 1024; setrlimit(RLIMIT_AS, mem_rlimit); } static int Run(const std::string file_name, int _cpu_limit, int _mem_limit) { std::string std_in PathUtil::StdIn(file_name); std::string std_out PathUtil::StdOut(file_name); std::string std_error PathUtil::StdError(file_name); std::string _excute PathUtil::Exe(file_name); umask(0); int std_infd open(std_in.c_str(), O_CREAT | O_RDONLY, 0644); int std_outfd open(std_out.c_str(), O_CREAT | O_WRONLY, 0644); int std_errorfd open(std_error.c_str(), O_CREAT | O_WRONLY, 0644); int fd fork(); if (fd 0) { LOG(LogLevel::ERROR) fork error; close(std_infd); close(std_outfd); close(std_errorfd); return -1; } else if (fd 0) { dup2(std_infd, 0); dup2(std_outfd, 1); dup2(std_errorfd, 2); SetProcLimit(_cpu_limit, _mem_limit); execl(_excute.c_str(), _excute.c_str(), nullptr); LOG(LogLevel::ERROR) execl error; exit(1); } else { int status; close(std_infd); close(std_outfd); close(std_errorfd); waitpid(fd, status, 0); LOG(LogLevel::INFO) 运行完毕 : (status 0x7F); return status 0x7f; } }下面我们来介绍一个库,这个库中的方法可以帮助我们轻松实现序列化和反序列化这个库怎么使用呢?我来演示一下#include compile.hpp #include jsoncpp/json/json.h #includerun.hpp int main() { // Compile::my_compile(code); // //int nns_run::Run(code); Json::Value in_value; in_value[code]zhangsan; in_value[age]18; Json::StyledWriter writer; std::string outwriter.write(in_value); std::coutout; Json::Value out_value; Json::Reader read; read.parse(out,out_value); std::string codeout_value[code].asCString(); int ageout_value[age].asInt(); std::coutcode\nagestd::endl; return 0; }具体上是怎么使用的呢?首先我们需要定义出一个Json::value假设我们需要进行序列化,我们就将我们需要序列话的数据进行填写然后定义出一个 Json::StyledWriter 对象将我们的value值写入到字符串中读取的话就是类似的步骤,首先定义出一个value对象和一个Reader对象,调用相关的读函数将我们需要读的json字符串读取到我们的value中然后读取value中的数据合并代码(编译和运行--引入json库)#include jsoncpp/json/json.h #include run.hpp #include compile.hpp #include ../comm/util.hpp #include ../comm/Log.hpp using namespace LogMoudle; using namespace util; class com_run { public: com_run() { } ~com_run() { } public: static std::string StuToCode(int stu_code, const std::string file_name) { std::string out; switch (stu_code) { case 0: out 编译运行成功; break; case -1: out 代码为空; break; case -2: out 未知错误; break; case -3: FileUtil::ReadFile(file_name, out, true); break; case SIGABRT: out 内存超出限制; break; case SIGXCPU: out cpu运行时间超限; break; case SIGFPE: out 浮点数溢出; break; default: break; } return out; } // code // input // cpulimit // memlimit static void Start(const std::string in_json, std::string *out_json) { Json::Value in_value; Json::Reader read; read.parse(in_json, in_value); std::string code in_value[code].asCString(); std::string input in_value[input].asCString(); int cpulimit in_value[cpulimt].asInt(); int memlimit in_value[memlimt].asInt(); int stu_code 0; int run_code 0; std::string file_name; Json::Value out_value; if (code.size() 0) { // 代码为空 stu_code -1; goto END; } file_name FileUtil::MakeUniqueFileName(); if (!FileUtil::WriteFile(PathUtil::Src(file_name), code)) { stu_code -2; // 未知错误 goto END; } if (!Compile::my_compile(file_name)) { stu_code -3; // 编译错误 goto END; } run_code ns_run::Run(file_name, cpulimit, memlimit); if (run_code 0) { stu_code -2; goto END; } else if (run_code 0) { stu_code run_code; goto END; } else { stu_code 0; } END: out_value[stu] stu_code; out_value[reason] StuToCode(stu_code, file_name); if (stu_code 0) { std::string out_put; FileUtil::ReadFile(PathUtil::StdOut(file_name), out_put, true); out_value[output] out_put; std::string _stderror; FileUtil::ReadFile(PathUtil::StdError(file_name), _stderror, true); out_value[stderror] _stderror; } Json::StyledWriter writer; *out_jsonwriter.write(out_value); } };现在我们的代码完成了合并的工作现在我们就可以对传来的json串进行编译和运行了,但是我们每次工作都会生成许许多多的临时文件,我们需要在工作的收尾部分对这些产生的临时文件进行删除删除临时文件static void RvTempFile(const std::string file_name) { std::string SRCPathUtil::Src(file_name); if(FileUtil::IsFileExists(SRC)) { unlink(SRC.c_str()); } std::string STDERRORPathUtil::StdError(file_name); if(FileUtil::IsFileExists(STDERROR)) { unlink(STDERROR.c_str()); } std::string _compile_errorPathUtil::CompilerError(file_name); if(FileUtil::IsFileExists(_compile_error)) { unlink(_compile_error.c_str()); } std::string _exePathUtil::Exe(file_name); if(FileUtil::IsFileExists(_exe)) { unlink(_exe.c_str()); } std::string _stdinPathUtil::StdIn(file_name); if(FileUtil::IsFileExists(_stdin)) { unlink(_stdin.c_str()); } std::string _stdoutPathUtil::StdOut(file_name); if(FileUtil::IsFileExists(_stdout)) { unlink(_stdout.c_str()); } }现在我们的项目中的编译和运行的模块基本完成

相关新闻

七、Vue组件

七、Vue组件

2026/8/14 15:12:43

一、组件定义 你可以把“组件”想象成乐高积木。在 Vue 中,我们不再是一笔一划地写一整个大网页,而是把网页拆分成一个个独立、可复用的小积木(比如导航栏、按钮、文章列表),然后像搭积木一样把它们拼起来。 1. 组件定…

大模型读懂文档了吗——多模态RAG的文档理解

大模型读懂文档了吗——多模态RAG的文档理解

2026/8/14 15:12:42

摘要 文档理解是多模态RAG系统的"第一公里",这一步的质量决定整个系统的上限——垃圾进,垃圾出。本文从多维分类体系出发,梳理不同文档类型对模型感知、结构理解、语义推理三层能力的差异化挑战,结合半导体显示领域的典…

继承(全)

继承(全)

2026/8/14 15:12:42

目录 一. 继承的概念及定义 1.1 继承的概念 1.2 继承的机制 1.3 继承的定义 1.3.1 定义格式​编辑 1.3.2 继承父类成员访问方式的变化 1.4 继承类模板 二. 父类和子类对象赋值兼容转换 2.2 类型转换的特殊处理规则 2.3 应用实例 三. 继承中的作用域 3.1 隐藏规则 …

在PPT中画一个圆 如何在圆上均匀布置点

在PPT中画一个圆 如何在圆上均匀布置点

2026/8/14 16:22:45

假设已经画好了一个圆:画第一个小点插入一个很小的实心圆;按住 Shift 画成正圆;放在大圆的最上方,圆心对准大圆的竖直中心线。画一个辅助正方形画一个正方形,尺寸与大圆的外接正方形完全一样;正方形与大圆 …

OpenCore配置工具OCAT使用指南:免费跨平台搞定黑苹果EFI维护

OpenCore配置工具OCAT使用指南:免费跨平台搞定黑苹果EFI维护

2026/8/14 16:22:45

OpenCore配置工具OCAT使用指南:免费跨平台搞定黑苹果EFI维护 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCAuxiliaryTools 你是否也有…

提示词工程进阶——让大模型输出你想要的JSON格式

提示词工程进阶——让大模型输出你想要的JSON格式

2026/8/14 16:22:45

提示词工程进阶——让大模型输出你想要的JSON格式 一个金融爱好者的AI学习手记 第18篇 第12篇我们学会了“调用”,但有一个问题没解决 第12篇,我们学会了用5行代码调用大模型API: response = client.chat.completions.create(model="deepseek-chat",messages=[…

Agent 评测的数据飞轮:如何把 Good Case 和 Bad Case 变成回归资产

Agent 评测的数据飞轮:如何把 Good Case 和 Bad Case 变成回归资产

2026/8/14 16:22:45

👤 个人主页:zzz_2368 🧪 系列主题:Agent 评测|从结果、轨迹到持续迭代 🔥 热门专栏:Agent | 小z的碎碎念 | Java后端 📚 本系列内容:评测体系、Rubric、Good Case、Bad …

同城中台系统核心表设计与模块启用状态机(代码深讲)

同城中台系统核心表设计与模块启用状态机(代码深讲)

2026/8/14 16:22:45

县城创业者评估「同城中台系统」时,技术侧常纠结功能捆绑:是否必须一次启用全部业务域?下文用模块注册表、启用状态机与 Service 伪代码说明「统一中台 按需启用模块」如何落地,并给出低成本试水期的联调验收点。示例为教学示意。…

Kimi    LeetCode 3906. 统计网格路径中好整数的数目 Python3实现

Kimi LeetCode 3906. 统计网格路径中好整数的数目 Python3实现

2026/8/14 16:12:45

根据搜索结果,LeetCode 3906「统计网格路径中好整数的数目」的 Python3 实现如下:---思路1. 预处理关键位置:directions 包含 3 个 D 和 3 个 R,从 (0,0) 出发,共经过 7 个格子(含起点)。将这些…

比较好的亚太EMBA,问了6位校友师资差别真的挺大

比较好的亚太EMBA,问了6位校友师资差别真的挺大

2026/8/13 11:01:28

比较好的亚太EMBA核心差异先看什么?对于希望兼顾工作与系统管理能力提升的亚太区高管而言,筛选匹配度高的EMBA项目时,师资配置是决定学习体验与实际收获的核心要素之一。我们结合3-4个公开信息透明、办学历史较长的亚太区主流EMBA项目特点&am…

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

2026/8/14 10:48:24

备考海外游学的亚洲EMBA面试,核心要围绕项目国际化设计逻辑、个人跨文化管理经验匹配度两个维度准备,避免把游学模块等同于普通旅游参访的认知偏差。不少备考者花3个月对比6份资料,却容易忽略面试官对“国际视野落地能力”的考察——比如香港…

比较好的国内EMBA,问了二十位校友聊透人脉价值

比较好的国内EMBA,问了二十位校友聊透人脉价值

2026/8/13 17:17:06

比较好的国内EMBA核心差异体现在哪些方面?比较好的国内EMBA的核心长期价值,很大程度上依托于校友网络的连接质量与资源生态的活跃度,这也是不少高管在择校时优先考量的因素。我们结合3-4个市场关注度较高的项目公开信息,从课程、师…

大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

2026/8/14 0:01:53

在这个数字化浪潮席卷全球的今天,企业想要在激烈的市场竞争中站稳脚跟,拥有一张好看的“数字名片”已经远远不够了。很多老板在刚开始接触互联网业务时,都有一个共同的困惑:为什么我花了钱建的网站,就像是在真空中自嗨?访客进来转了两圈就跑了,线索石沉大海,甚至连客服…

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

2026/8/14 0:01:54

在这个流量为王、视觉至上的互联网时代,对于临沂乃至整个山东乃至全国的传统中小企业来说,拥有一张精美的“数字名片”早已不再是可选项,而是生存的必答题。每当夜幕降临,沂河两岸灯火辉煌,物流之都的喧嚣逐渐沉淀为对未来的思考。我们常常听到老板们在茶余饭后探讨:为什…

Flutter与OpenHarmony实现剧本杀组队表单开发实战

Flutter与OpenHarmony实现剧本杀组队表单开发实战

2026/8/14 0:01:54

1. 项目概述在移动应用开发领域,跨平台框架Flutter因其高效的开发体验和出色的性能表现,已经成为众多开发者的首选。而OpenHarmony作为新兴的操作系统平台,其开放性和灵活性为开发者提供了全新的可能性。本文将聚焦于一个实际应用场景——剧本…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/8 5:07:31

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/9 13:42:46

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/8 2:30:15

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…