my_judged.cc 的初稿

2023-10-09 20:39
文章标签 cc judged 初稿

本文主要是介绍my_judged.cc 的初稿,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>  
#include <stdlib.h>
#include <unistd.h>   /* fork(), read函数、write函数和getpid函数*/
#include <syslog.h>   /*int syslog(int priority, string message); 本函数将 message 字符串写到系统纪录中 */
#include <errno.h>    // 出错码
#include <fcntl.h>    /* fcntl.h定义了很多宏和open */
#include <stdarg.h>   /* 让函数能够接收可变参数 */
#include <mysql/mysql.h>#include <sys/wait.h>  // 进程控制
#include <sys/stat.h>  // 文件状态  2-> waitpid().
#include <signal.h>    // 信号#define BUFFER_SIZE 1024
#define LOCKFILE "/var/run/judged.pid"  // 文件路径宏定义  /var/run/judged.pid
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) // 所有者可以 r 和 w, g 和 o 可以 r 。
#define STD_MB 1048576#define OJ_WT0 0 // Pending // 正等待...
#define OJ_WT1 1 // Pending_Rejudging
#define OJ_CI 2  // Compiling
#define OJ_RI 3  // Running_Judging
#define OJ_AC 4  // Accepted
#define OJ_PE 5  // Presentation Error
#define OJ_WA 6  // Wrong Answer
#define OJ_TL 7  // Time Limit Exceeded
#define OJ_ML 8  // Memory Limit Exceeded
#define OJ_OL 9  // Output Limit Exceeded
#define OJ_RE 10 // Runtime Error
#define OJ_CE 11 // Compilation Error
#define OJ_CO 12 // Compile_OKstatic char host_name[BUFFER_SIZE];
static char user_name[BUFFER_SIZE];
static char password [BUFFER_SIZE];
static char db_name  [BUFFER_SIZE];
static char oj_home  [BUFFER_SIZE];
static char oj_lang_set[BUFFER_SIZE];  // 
static int port_number;
static int max_running; // 可以运行的 judge_client 的数量上限。
static int sleep_time;  // 数据库轮询间隔
static int sleep_tmp;
static int oj_tot; // 老式并发处理中总的 judged 数量
static int oj_mod; // 老式并发处理中,本 judged 负责处理 solution_id 按照 TOTAL 取模后余数为几的任务。static bool STOP = false;static MYSQL *conn;   /************* 数据库 类型 *****************/
static MYSQL_RES *res;
static MYSQL_ROW row;static char query[BUFFER_SIZE];void call_for_exit(int s) {STOP = true;printf("Stopping judged...\n");
}
void write_log(const char *fmt, ...) {va_list ap;char buffer[4096];
//	time_t          t = time(NULL);
//	int             l;sprintf(buffer,"%s/log/client.log",oj_home);FILE *fp = fopen(buffer, "a+");if (fp == NULL){fprintf(stderr, "openfile error!\n");system("pwd");} va_start(ap, fmt);vsprintf(buffer, fmt, ap);fprintf(fp,"%s\n",buffer);va_end(ap);fclose(fp);
}int after_equal(char * c){int i=0;for(; c[i] != '\0' && c[i] != '='; i++);return ++i;
}
void trim(char * c){char buf[BUFFER_SIZE];char * start,*end;strcpy(buf,c);start=buf;while(isspace(*start)) start++;end=start;while(!isspace(*end)) end++;*end='\0';strcpy(c,start);
}
bool read_buf(char * buf,const char * key,char * value){if (strncmp(buf, key, strlen(key)) == 0) {strcpy(value, buf + after_equal(buf));trim(value);	return 1;}return 0;
}
void read_int(char * buf,const char * key,int * value){char buf2[BUFFER_SIZE];if (read_buf(buf, key, buf2))sscanf(buf2, "%d", value);
}
// read the configue file
void init_mysql_conf() {FILE *fp = NULL; // 文件指针类型 fpchar buf[BUFFER_SIZE];host_name[0] = 0;user_name[0] = 0;password[0] = 0;db_name[0] = 0;port_number = 3306;max_running = 3; // 最多允许 3 个 judge_client 同时存在。sleep_time = 3; oj_tot = 1;  // 老式并发处理中总的 judged 数量  oj_mod = 0;  // 老式并发处理中,本 judged 负责处理 solution_id 按照 TOTAL 取模后余数为几的任务。strcpy(oj_lang_set, "0, 1");fp = fopen("./etc/judge.conf", "r");if(fp != NULL){while(fgets(buf, BUFFER_SIZE - 1, fp)) {read_buf(buf, "OJ_HOST_NAME", host_name);	read_buf(buf, "OJ_USER_NAME", user_name);read_buf(buf, "OJ_PASSWORD", password);read_buf(buf, "OJ_DB_NAME", db_name);read_int(buf , "OJ_PORT_NUMBER", &port_number);read_int(buf, "OJ_RUNNING", &max_running);read_int(buf, "OJ_SLEEP_TIME", &sleep_time);read_int(buf , "OJ_TOTAL", &oj_tot);read_int(buf,"OJ_MOD",&oj_mod);read_buf(buf,"OJ_LANG_SET", oj_lang_set);}sprintf(query,"SELECT solution_id FROM solution WHERE language in (%s) and result<2 and MOD(solution_id,%d)=%d ORDER BY result ASC,solution_id ASC limit %d", oj_lang_set, oj_tot, oj_mod, max_running*2);sleep_tmp = sleep_time;//	fclose(fp);}
}
void run_client(int runid, int clientid){char buf[BUFFER_SIZE],runidstr[BUFFER_SIZE];struct rlimit LIM;LIM.rlim_max=800;LIM.rlim_cur=800;setrlimit(RLIMIT_CPU,&LIM);LIM.rlim_max=80*STD_MB;LIM.rlim_cur=80*STD_MB;setrlimit(RLIMIT_FSIZE,&LIM);LIM.rlim_max=STD_MB<<11;LIM.rlim_cur=STD_MB<<11;setrlimit(RLIMIT_AS,&LIM);LIM.rlim_cur=LIM.rlim_max=200;setrlimit(RLIMIT_NPROC, &LIM);//buf[0]=clientid+'0'; buf[1]=0;sprintf(runidstr, "%d", runid);sprintf(buf, "%d", clientid);execl("/usr/bin/judge_client", "/usr/bin/judge_client", runidstr, buf, oj_home, (char *)NULL);
}
int executesql(const char * sql) {if (mysql_real_query(conn, sql, strlen(sql))) { // 成功,函数返回零sleep(20);conn = NULL;return 1;} elsereturn 0;
}
int init_mysql(){if(conn == NULL){conn = mysql_init(NULL);		// init the database connection/* connect the database */const char timeout = 30;mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);if(!mysql_real_connect(conn, host_name, user_name, password, db_name, port_number, 0, 0)) {sleep(20);return 1; // 连接失败,mysql_real_connect 返回为 0.}}if (executesql("set names utf8"))return 1; // 执行失败return 0;
}
int  _get_jobs_mysql(int * jobs) {if (mysql_real_query(conn, query, strlen(query))) { // 成功返回 0, 读取未判的那些 solution_id 们。sleep(20); // 不存在 pending 中的 solution_id , 进程挂起 20 秒。return 0;}res = mysql_store_result(conn);int i = 0;int ret = 0;while((row = mysql_fetch_row(res)) != NULL) {jobs[i++] = atoi(row[0]); }ret = i;while(i <= max_running*2) jobs[i++] = 0;return ret;
}
int get_jobs(int * jobs) {return _get_jobs_mysql(jobs);
}
bool _check_out_mysql(int solution_id, int result) { // workcnt < max_running && check_out(runid, OJ_CI)char sql[BUFFER_SIZE];sprintf(sql, "UPDATE solution SET result=%d,time=0,memory=0,judgetime=NOW() WHERE solution_id=%d and result<2 LIMIT 1",result, solution_id);if (mysql_real_query(conn, sql, strlen(sql))) {syslog(LOG_ERR | LOG_DAEMON, "%s",mysql_error(conn));return false;} else {if(mysql_affected_rows(conn) > 0ul)return true;elsereturn false;}
}
bool check_out(int solution_id, int result) {return _check_out_mysql(solution_id, result);
}
int work() {static  int retcnt = 0;int i = 0;static pid_t ID[100];  // 声明 100 大小的pid数组。static int workcnt = 0;int runid = 0;int jobs[max_running*2+1];  // max_running 是启动 judge_client 的上限pid_t tmp_pid = 0;/* get the database info */if(!get_jobs(jobs)) retcnt = 0; //  检索出的 solution_id 们,全都存在 jobs[] 中。retcnt 为 pending的solution_id的数量。/* exec the submit */for (int j = 0; jobs[j] > 0; j++) {runid = jobs[j];if (workcnt >= max_running) {    // if no more client can runningtmp_pid = waitpid(-1, NULL, 0);     // wait 4 one child exit, pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样workcnt--; retcnt++; // waitpid 返回收集到的子进程的进程ID, retcnt++, 这是hp?for (i = 0; i < max_running; i++)     // get the client idif (ID[i] == tmp_pid) break; // got the client idID[i] = 0;} else {                                                  // have free clientfor (i = 0; i < max_running; i++)     // find the client idif (ID[i] == 0) break;    // got the client id}if(workcnt < max_running && check_out(runid, OJ_CI)) { // 要判题了,将result置为 OJ_CIworkcnt++;                                        // client 增加一个。ID[i] = fork();                                   // start to forkif (ID[i] == 0) {run_client(runid, i);    // if the process is the son, run it,儿子你去判题吧,父亲继续运行。exit(0);}} else ID[i] = 0;}//下面回收运行完的进程号while ( (tmp_pid = waitpid(-1, NULL, WNOHANG) ) > 0) { // 如果使用了WNOHANG(wait no hung)参数调用waitpid,即使没有子进程退出,它也会立即返回workcnt--; retcnt++;   // 可能是立即返回,子进程没有主动退出的,也会立即终止一个子进程。for (i = 0; i < max_running; i++)     // get the client idif (ID[i] == tmp_pid) break;      // got the client idID[i] = 0;printf("tmp_pid = %d\n", tmp_pid);}mysql_free_result(res);                         // free the memoryexecutesql("commit");//free(ID);//free(jobs);return retcnt;
}
int lockfile(int fd) {struct flock fl;fl.l_type = F_WRLCK; // 独占性写锁定fl.l_start = 0;fl.l_whence = SEEK_SET; // SEEK_SET 文件头fl.l_len = 0;return (fcntl(fd, F_SETLK, &fl)); // F_SETLK 设置文件锁定的状态, 如果无法锁定返回 -1.
}
int already_running(){int fd;char buf[16];fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE); // "/var/run/judged.pid" (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)Permits the file's owner to read it.if (fd < 0){syslog(LOG_ERR|LOG_DAEMON, "can't open %s: %s", LOCKFILE, strerror(errno));exit(1);}if(lockfile(fd) < 0){      if (errno == EACCES || errno == EAGAIN){close(fd);return 1;}syslog(LOG_ERR|LOG_DAEMON, "can't lock %s: %s", LOCKFILE, strerror(errno));exit(1);}ftruncate(fd, 0); // 以写模式打开的文件,就理解为清空文件吧!先!sprintf(buf, "%d", getpid()); // getpid() 返回当前进程标识,将当前进程标识写入到 /var/run/judged.pidwrite(fd, buf, strlen(buf)+1);return (0);
}
int daemon_init(void) {pid_t pid;if((pid = fork()) < 0) return(-1);else if(pid != 0) exit(0);  /* parent exit *//* child continues */setsid(); /* become session leader */chdir(oj_home);  /* change working directory */umask(0);        /* clear file mode creation mask */close(0); /* close stdin */  // 切后台关闭这三个干嘛呀!close(1); /* close stdout */close(2); /* close stderr */return(0); 
}
int main(int argc, char** argv){strcpy(oj_home, "/home/judge");chdir(oj_home);daemon_init(); // 切后台if (strcmp(oj_home, "/home/judge") == 0 && already_running() ){syslog(LOG_ERR|LOG_DAEMON, "This daemon program is already running!\n"); // err, daemonreturn 1;  // syslogd守护进程用于解决守护进程的日志记录问题,openlog、syslog和closelog,日志信息会写入syslog.conf文件指定的位置}init_mysql_conf();	// set the database infosignal(SIGQUIT, call_for_exit); // 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程signal(SIGKILL, call_for_exit); // 无法处理和忽略。中止某个进程signal(SIGTERM, call_for_exit); // 请求中止进程,kill命令缺省发送int j = 1;while (!STOP){			// start to runwhile( j && (!init_mysql()) ){        j = work();		}sleep(sleep_time); // judged 通过轮询数据库发现新任务,轮询间隔的休息时间,单位秒, 对应流程图。j = 1;}return 0;
}
all: my_judged2.cc
	g++ -Wall -c -I/usr/local/mysql/include/mysql -I/usr/include/mysql  my_judged2.cc
	g++ -Wall -o my_judged2 my_judged2.o -L/usr/local/mysql/lib/mysql -L/usr/lib/mysql  -lmysqlclient
// Special thanks to teacher Zhang for helping me.

这篇关于my_judged.cc 的初稿的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/175417

相关文章

Adobe After Effects的插件--------CC Particle World

CC Particle World是一个粒子效果器,用于在三维空间中生成和模拟各种粒子系统,包括火焰、雨、雪、爆炸、烟雾等等。它会自动随时间变化发射粒子。 本文部分参照 https://www.163.com/dy/article/IEJVDN760536FE6V.html 使用条件 使用该插件的图层需是2D图层。 我们新建一个纯色图层(也可以是其他类型图层),作为【效果控件载体图层】

蓝牙--关于bta_ag_sdp.cc文件的讲解

讲解代表之前先简单介绍下HF和AG HF(Hands-Free unit)测:是指作为音频网关的远程音频输入和输出机制的设备。它还提供了一些远程控制手段。在蓝牙通信中,HF通常是支持HFP(Hands-Free Profile)协议的设备,例如蓝牙耳机、汽车蓝牙系统等。 AG(Audio Gateway)测:是指作为音频的输入和输出网关的设备。典型的充当音频网关的设备包括手机。 我们这边主要

蓝牙--关于bta_ag_sco.cc文件的讲解

讲解代表之前先简单介绍下HF和AG HF(Hands-Free unit)测:是指作为音频网关的远程音频输入和输出机制的设备。它还提供了一些远程控制手段。在蓝牙通信中,HF通常是支持HFP(Hands-Free Profile)协议的设备,例如蓝牙耳机、汽车蓝牙系统等。 AG(Audio Gateway)测:是指作为音频的输入和输出网关的设备。典型的充当音频网关的设备包括手机。 我们这边主要

蓝牙--关于bta_ag_rfc.cc文件的讲解

讲解代表之前先简单介绍下HF和AG HF(Hands-Free unit)测:是指作为音频网关的远程音频输入和输出机制的设备。它还提供了一些远程控制手段。在蓝牙通信中,HF通常是支持HFP(Hands-Free Profile)协议的设备,例如蓝牙耳机、汽车蓝牙系统等。 AG(Audio Gateway)测:是指作为音频的输入和输出网关的设备。典型的充当音频网关的设备包括手机。 我们这边主要

蓝牙--关于bta_ag_main.cc文件的讲解

讲解代表之前先简单介绍下HF和AG HF(Hands-Free unit)测:是指作为音频网关的远程音频输入和输出机制的设备。它还提供了一些远程控制手段。在蓝牙通信中,HF通常是支持HFP(Hands-Free Profile)协议的设备,例如蓝牙耳机、汽车蓝牙系统等。 AG(Audio Gateway)测:是指作为音频的输入和输出网关的设备。典型的充当音频网关的设备包括手机。 我们这边主要

Photoshop CC 2019圆形的抠图

快速进入矩形选区 快速在矩形和圆形选区之前切换: shift+M 选择的时候,按住shift,可以选中正方形/圆形   以中心点画圆: alt + 拖拽 再利用变换选区功能即可实现圆的选中 效果如图所示: 再使用自由变换,即可放大,缩小球的大小: ctrl + T 阴影部分的处理: 1)去其他球那里选择个椭圆形选区 2)选择编辑-填充 3)使用滤镜里

CC工具箱使用指南:【整库计算BSM】

一、简介 这是一个批量计算【BSM】的小工具。 一般的数据库要素或表格都有一个【BSM】字段,用来标识唯一值。 【BSM】的计算一般都有同样的规律,前缀+中间的填充数字+OBJECT码。 二、工具参数介绍 在工程目录栏中,右键点击要处理的GDB数据库,选择【CC工具箱】组里的【整库计算BSM】工具: 即可打开下面的工具框界面: 1、输入前缀 这个前缀看数据库成果的要求

网站频繁受到CC攻击该怎样做好防护?

CC攻击主要是针对网络服务器或者是网络设备的攻击,属于一种特定的分布式拒绝服务攻击类型,攻击者会向目标服务器发送大量的连接请求,以此来占用大量的服务器资源,使服务器无法正常运行或者是网络迟钝,给企业造成一定的经济损失。 那当网站频繁受到CC攻击时该怎样做好防护呢? 企业可以使用CDN技术,CDN是一种分布式网络架构,可以通过将网站的静态资源缓存到全球各地的服务器上,能够提高网站的访问速

Photoshop cc 2015 导出web所用格式提示错误 无法完成该操作怎么办?用这个方法轻松解决!

一、首先打开电脑点击开始菜单,运行并点击打开cmd窗口,输入框内输入regedit   二、找到计算机\HKEY_CURRENT_USER\Software\Adobe\Photoshop\110.0或者120.0      三、接着右击新建-DWORD值,并命名为OverridePhysicalMemoryMB        四、鼠标双击新建的文件夹,数值数据输入2

cc: 未找到命令 Command not found

问题 在用Cygwin进行make的时候提示了 sh\bin cc: 未找到命令。 原因 代表着应该是C Compiler没有安装到。虽然Cygwin里面有携带,但在默认安装情况下是不会有的。 解决方法 重新运行Cygwin安装包,修改默认安装模式: 这样会完整地把东西都下载下来。 按照更准确地解决方法应该是进去Devel里找到C Compiler进行下载即可,但我似乎没