From cc0f720de91a02a92979262133c533dd6d81d470 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 6 Jul 2015 19:20:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC=E5=92=8C=E9=83=A8=E5=88=86typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要是将类的私有变量进行了重命名,改为_开头 --- judge/client.py | 115 +++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 61 deletions(-) diff --git a/judge/client.py b/judge/client.py index 5cae0ac..aa9373b 100644 --- a/judge/client.py +++ b/judge/client.py @@ -1,4 +1,5 @@ # coding=utf-8 +import json import commands import hashlib from multiprocessing import Pool @@ -14,7 +15,7 @@ class JudgeClientException(Exception): # 下面这个函数作为代理访问实例变量,否则Python2会报错,是Python2的已知问题 # http://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when-using-pythons-multiprocessing-pool-ma/7309686 def _run(instance, test_case_id): - return instance.judge_one(test_case_id) + return instance._judge_one(test_case_id) class JudgeClient(object): @@ -26,72 +27,69 @@ class JudgeClient(object): :param max_cpu_time: 最大cpu时间,单位ms :param max_real_time: 最大执行时间,单位ms :param max_memory: 最大内存,单位MB - :param test_case_dir: 测试用户文件夹路径 + :param test_case_dir: 测试用例文件夹路径 :return:返回结果list """ - self.language = language - self.exec_file_path = exec_file_path - self.max_cpu_time = max_cpu_time - self.max_real_time = max_real_time - self.max_memory = max_memory - self.test_case_dir = test_case_dir + self._language = language + self._exec_file_path = exec_file_path + self._max_cpu_time = max_cpu_time + self._max_real_time = max_real_time + self._max_memory = max_memory + self._test_case_dir = test_case_dir # 进程池 - self.pool = Pool(processes=max_running_number) - # 结果数组 - self.results = [] + self._pool = Pool(processes=max_running_number) # 测试用例配置项 - self.test_case_info = self.load_test_case_info() + self._test_case_info = self._load_test_case_info() - def load_test_case_info(self): + def _load_test_case_info(self): # 读取测试用例信息 转换为dict - # try: - # f = open(self.test_case_dir + "info") - # return json.loads(f.read()) - # except IOError: - # raise JudgeClientException("Test case config file not found") - # except ValueError: - # raise JudgeClientException("Test case config file format error") - return {"test_case_number": 2, - "test_cases": - { - "1": {"input_name": "1.in", - "output_name": "1.out", - "output_md5": "b10a8db164e0754105b7a99be72e3fe5", - "output_size": 100}, + try: + f = open(self._test_case_dir + "info") + return json.loads(f.read()) + except IOError: + raise JudgeClientException("Test case config file not found") + except ValueError: + raise JudgeClientException("Test case config file format error") + # return {"test_case_number": 2, + # "test_cases": + # { + # "1": {"input_name": "1.in", + # "output_name": "1.out", + # "output_md5": "b10a8db164e0754105b7a99be72e3fe5", + # "output_size": 100}, + # + # "2": {"input_name": "2.in", + # "output_name": "2.out", + # "output_md5": "3e25960a79dbc69b674cd4ec67a72c62", + # "output_size": 100} + # }, + # "output_total_size": 200 + # } - "2": {"input_name": "2.in", - "output_name": "2.out", - "output_md5": "3e25960a79dbc69b674cd4ec67a72c62", - "output_size": 100} - }, - "output_total_size": 200 - } - - def generate_command(self, test_case_id): + def _generate_command(self, test_case_id): """ 设置相关运行限制 进制访问网络 如果启用tmpfs 就把代码输出写入tmpfs,否则写入硬盘 """ # todo 系统调用白名单 chroot等参数 - # fixme 时间的单位问题 command = "lrun" + \ - " --max-cpu-time " + str(self.max_cpu_time / 1000.0) + \ - " --max-real-time " + str(self.max_real_time / 1000.0) + \ - " --max-memory " + str(self.max_memory * 1000 * 1000) + \ + " --max-cpu-time " + str(self._max_cpu_time / 1000.0) + \ + " --max-real-time " + str(self._max_real_time / 1000.0) + \ + " --max-memory " + str(self._max_memory * 1000 * 1000) + \ " --network false" + \ " --uid " + str(lrun_uid) + \ " --gid " + str(lrun_gid) - if self.language == Language.JAVA: - command += (" java " + self.exec_file_path) + if self._language == Language.JAVA: + command += (" java " + self._exec_file_path) else: - command += (" " + self.exec_file_path) + command += (" " + self._exec_file_path) - command += (" 0<" + self.test_case_dir + str(test_case_id) + ".in" + + command += (" 0<" + self._test_case_dir + str(test_case_id) + ".in" + " 1>" + judger_workspace + str(test_case_id) + ".out" + " 3>&2") return command - def parse_lrun_output(self, output): + def _parse_lrun_output(self, output): lines = output.split("\n") if len(lines) != 7: raise JudgeClientException("Lrun result parse error") @@ -128,8 +126,8 @@ class JudgeClient(object): result[translate[name]] = translate[value] return result - def compare_output(self, test_case_id): - test_case_md5 = self.test_case_info["test_cases"][str(test_case_id)]["output_md5"] + def _compare_output(self, test_case_id): + test_case_md5 = self._test_case_info["test_cases"][str(test_case_id)]["output_md5"] output_path = judger_workspace + str(test_case_id) + ".out" try: @@ -147,18 +145,16 @@ class JudgeClient(object): md5.update(data) # 对比文件是否一致 - print "my", md5.hexdigest() - print test_case_md5 # todo 去除最后的空行 return md5.hexdigest() == test_case_md5 - def judge_one(self, test_case_id): + def _judge_one(self, test_case_id): # 运行lrun程序 接收返回值 - command = self.generate_command(test_case_id) + command = self._generate_command(test_case_id) status_code, output = commands.getstatusoutput(command) if status_code: raise JudgeClientException(output) - run_result = self.parse_lrun_output(output) + run_result = self._parse_lrun_output(output) run_result["test_case_id"] = test_case_id @@ -179,24 +175,21 @@ class JudgeClient(object): # 下面就是代码正常运行了 需要判断代码的输出是否正确 - if self.compare_output(test_case_id): + if self._compare_output(test_case_id): run_result["result"] = Result.ACCEPTED else: run_result["result"] = Result.WRONG_ANSWER return run_result - def collect_result(self, result): - self.results.append(result) - def run(self): # 添加到任务队列 _results = [] results = [] - for i in range(self.test_case_info["test_case_number"]): - _results.append(self.pool.apply_async(_run, (self, i + 1))) - self.pool.close() - self.pool.join() + for i in range(self._test_case_info["test_case_number"]): + _results.append(self._pool.apply_async(_run, (self, i + 1))) + self._pool.close() + self._pool.join() for item in _results: # 注意多进程中的异常只有在get()的时候才会被引发 # http://stackoverflow.com/questions/22094852/how-to-catch-exceptions-in-workers-in-multiprocessing @@ -211,7 +204,7 @@ class JudgeClient(object): # 不同的pool之间进行pickle的时候要排除自己,否则报错 # http://stackoverflow.com/questions/25382455/python-notimplementederror-pool-objects-cannot-be-passed-between-processes self_dict = self.__dict__.copy() - del self_dict['pool'] + del self_dict['_pool'] return self_dict