当前位置: 首页 > wzjs >正文

洛阳网站建设电话灰色行业推广

洛阳网站建设电话,灰色行业推广,徐州优化网站建设,莆田建设项目环境网站【HUSTOJ 判题机源码解读系列02】judged 守护进程工作流程 1. judged 工作流程 上回说到,HUSTOJ 判题机源码中最重要的两个 C 语言文件为: judge.ccjudge_client.cc judge.cc 会被编译为可执行性文件 judged 后复制到 /usr/bin 目录下。 judge_clie…

【HUSTOJ 判题机源码解读系列02】judged 守护进程工作流程

1. judged 工作流程

上回说到,HUSTOJ 判题机源码中最重要的两个 C 语言文件为:

  • judge.cc
  • judge_client.cc

judge.cc 会被编译为可执行性文件 judged 后复制到 /usr/bin 目录下。

judge_client.cc 会被编译为可执行文件 judge_client 后复制到 /usr/bin 目录下。

随后,执行 sudo judged 命令就可以启动 judged 进程,此时,judged 进程作为一个守护进程,会定时的去查询数据库中的 solution 表,从 solution 表中获取等待评测的题目,最后指派一个 judge_client 进程去执行判题的逻辑。

以上就是 judged的大致的工作原理。

在复习完毕 judged 原理后,在这里我们先把后文的结构整体安排介绍一下:

  1. 通过简化的核心代码,分析源码的整体框架
  2. 解析源码中持续判题的流程,这点比较重要

2. 源码整体框架

在解读源码时,首先需要梳理 main 函数的整体框架和主要功能。

由于关注的是整体结构,这里省略了大部分代码,仅保留最核心的逻辑。部分内容进行了简化,或以注释替代,详细版本将在后文展开。

#define MAX_JOBS 100static int STOP = false;// 执行判题程序
void run_client(int runid, int clientid) {char runid_str[10], clientid_str[10];execl("/usr/bin/judge_client", "/usr/bin/judge_client", runid_str, clientid_str, NULL);
}// 从数据库获取任务
void get_jobs(int* jobs) {int* data = get_data_from_mysql();if (data != NULL) {memcpy(jobs, data, MAX_JOBS * sizeof(int));}
}void work() {int jobs[MAX_JOBS] = {0};get_jobs(jobs);for (int i = 0; jobs[i] > 0; i++) {pid_t pid = fork();if (pid == 0) {  // 子进程run_client(jobs[i], i);exit(0);}}
}int main() {// 主循环,不断获取任务并处理,直到 STOP 标志被设置为 truewhile (!STOP) {work();sleep(1);  // 休息一秒,免得对数据库造成的压力过大}return 0;
}

整体逻辑如下:

  • main() 函数不断的调用 work() 函数从数据库中获取题目
  • work() 函数不断的创建子进程去执行 run_client() 函数
  • run_client() 函数驱动 judge_client 去真正的执行判题任务
  • STOP 变量控制了主循环执行,因为是全局变量,其他地方可以修改这个变量让主循环停止执行,终止判题

整个框架逻辑都十分简单,接下来我们再看一下源码中是怎么以比较简单的方式实现持续判题的功能的。

3. 持续判题流程实现

在前文对源码整体框架的解读中,main 函数中只展示了一个 while 死循环:

while (!STOP) {work();sleep(1);
}

但是在完整的代码里面,其实是有两个 while 死循环的,这两个 while 死循环和 work() 函数与 get_jobs() 函数一起相互配合工作。解决了上面单个死循环会出现的一个比较严重的问题,同时这也是我个人认为 judge.cc 文件中设计的挺优秀的一段代码。

OK,我们来分析一下上面的这个死循环的问题,其实就两句代码:work()sleep()work() 执行派发判题的任务,sleep()休息一秒钟,避免无限轮询数据库,给数据库干崩了。咋一看没什么问题,但是如果有一个提交,刚好在 sleep() 函数休息前的那一刻进来了,那这个提交就会有一个 1 秒的空窗期,因为判题机休息了。。。。。。好像没什么问题,休息完再给你判嘛(bushi

一个提交好像并不能看出问题,那现在想想一个场景,此时判题机正在给一个大型比赛判题,每次进来的题目都很多,但是这个判题机每次都固定只判一批题目,然后都要休息一秒后再判,雷打不动(判题机:“work life balance”)。那判题的效率就十分低效了。

所以现在我们希望判题机最起码需要符合以下两点要求:

  1. 不能干崩数据库
  2. 在大型比赛这种场景,我们希望判题机加班判题

在不采用事件驱动实现判题机代码的限制下,我们现在就来看一下作者是怎么通过双 while 死循环来实现以上的两点要求的。

以下的代码是我化简后的代码模型。

/*** @return int 本地从数据库获取了多少题*/
int get_jobs(int* jobs) {// 从数据库中获取需要判题int* solution_ids = get_data_from_mysql();jobs = solution_ids;// 这里直接返回从数据库中获取的题目数量return solution_ids 的长度;
}/*** @return int 本次 work () 函数执行,总共判了多少题*/
int work() {// retcnt 记录本次 work 函数判了多少道题int retcnt;int jobs[100];if (!get_jobs(jobs)) {return 0;}for (int i = 0; jobs[i] > 0; i++) {// 开始判 jobs[i] 对应的题目,// judge 函数是我虚构的, 在这里知道是判题即可judge(jobs[i]);// 判了一题, retcnt + 1retcnt++;}return retcnt;
}int main() {int j = 1;int n = 0;while (!STOP) {n = 0;while (j) {j = work();n += j;}if (n == 0) {sleep(1);}j = 1;}
}

在这里,我们来看一下 work() 函数的返回值和 get_jobs() 的返回值分别代表什么:

  • work():本次 work() 函数执行完毕后判了多少道题
  • get_jobs():本次 get_jobs() 函数从数据库中获取了多少题

明确了这两个返回值之后,再来看一下主函数中,j 变量和 n 变量分别是什么:

j = work();
n += j;

j 就是单次 work() 函数执行后判了多少题。 work() 每执行一次,就会返回当前获取到 jobs 中的判题数,并将这个判题数赋值给 j

n 则表示当前判题机从休息状态(sleep(1))恢复执行判题以来,在这一轮的循环中累计判了多少题。它在内层循环不断的累加 j 的值,直到 j == 0while (j) 退出,表示没有题目可以判了)。

简单来说:

  • j = work():代表执行一次判题任务,并记录了本次的判题数量。
  • n += j:代表在当前轮次中累计的判题数量。

所以我们现在就可以明确了。

在内层循环 while (j) 中,j == work(),如果 work() 判到了题,那么内层循环会一直执行,持续进行判题。

其次,在外层循环 while (!STOP) 中,由于 n 会不断累加内层的 j,即使某次 work() 没有判到题,导致内层循环退出,但由于此时 n > 0,意味着在当前较大的外层判题周期内,仍然有判题发生。因此,外层循环依然会继续执行判题逻辑,不会进入 sleep() 的分支。

吐槽一下:作者要是把 n 变量和 j 变量的命名规范化一下就好了,这里属实花了一点心思。

通过以上的这个双 while 死循环机制,我们就可以较好的完成我们上面的两点要求了。

到这里,judge.cc 相对来说比较难理解的地方就已经解读完毕了,其余一些具体的实现细节,由于提取出核心逻辑出来后也不好解读,需要以完整源码 + 注释的方式来展示了,但是毕竟源码有 900 + 行的,篇幅所限,下期再见。

http://www.dtcms.com/wzjs/178471.html

相关文章:

  • 对门户网站建设情况的报告广告语
  • 龙岗外贸网站建设公司东莞seo排名收费
  • 解决方案的网站建设windows优化大师和360哪个好
  • 专门做辅助的网站互联网广告推广是做什么的
  • 做h5免费软件有哪些网络优化工程师工资
  • 亚太建设科技信息研究院网站外贸网站seo推广教程
  • 黑河网站建设搜索引擎优化的基础是什么
  • 在别的公司做的网站可以转走吗广州最新疫情通报
  • 天河公司网站建设做外贸用什么软件找客户
  • 个旧市哪里有做网站网络热词2023
  • dede手机医院网站模板seo排名诊断
  • 临沧网站制作搜狐财经峰会直播
  • 今天出京入京最新通知女生做sem还是seo
  • 网站建设协议 模板域名申请哪家好
  • 做网站需要花钱吗百度站长工具seo查询
  • 佛山新网站制作渠道seo是什么车
  • 如何注册企业成都网站关键词推广优化
  • 深圳哪家网站建设公司好企业网站推广策划书
  • 企业网站建设制作设计哪家最专业如何做网站平台
  • 食品公司网站模板上海百度关键词优化公司
  • 做团购的网站有哪些成人职业技能培训学校
  • 平邑网站建设沧州网站seo公司
  • 黄浦网站建设推广国内广告联盟平台
  • 做企业网站代码那种好市场营销策略
  • mobi域名网站长春网站制作企业
  • 网站建设期任务及总结宁波谷歌优化
  • 内江市住房和城乡建设局网站电话号码网站推广什么意思
  • 怎样做网站策划aso优化运营
  • 做网站的书籍推荐广州seo关键词
  • 自已做好的网站怎么做后台关键词如何排名在首页