Time&Memory篇
(一)思路:
先利用subprocess.Popen(),调用外部命令执行程序,将.in文件输入,将程序运行结果保存在.out文件中。程序数据输入和结果保存完成了,接下来就是时间和内存的问题。通过pid获取进程号,然后利用psutil模块实现进程的控制与监听,即可完成一个简单的Time&Memory的判断。
(二)代码:
import time
import subprocess
import psutil
dir_work = "./"
fin = open("./main.in", "r+")
fout = open("./main.out", "w+")
p_cmd = { # 运行程序的命令,这里以C++、C语言为例
"gcc": "./main",
"g++": "./main",
}
def time_mem(language):
"""
执行程序获取执行时间与内存
"""
time_limit = 1 #second 时间限制
mem_limit = 128 * 1024 #kb 内存限制
max_rss = 0 #记录最大内存
problem_info = {} #时间单位ms 内存单位kb
p = subprocess.Popen(p_cmd[language],shell=True,cwd=dir_work, stdin=fin, stdout=fout, stderr=subprocess.PIPE) # cwd设置工作目录
start = time.time() #开始时间
print("程序开始运行的时间是%s" % start)
pid = p.pid
glan = psutil.Process(pid) #监听控制进程
while True:
time_now = time.time() - start # ??
if psutil.pid_exists(pid) is False: #运行错误
problem_info['time'] = time_now*1000
problem_info['memory'] = max_rss/1024.0
problem_info['result'] = "Runtime Error"
return problem_info
m_infor = glan.memory_info()
print(m_infor)
rss = m_infor[0] #获取程序占用内存空间 rss
if p.poll() == 0: #运行正常结束,跳出循环,继续判断
end = time.time()
break
if max_rss < rss:
max_rss = rss
#print("max_rss=%s" % max_rss) #debug
if time_now > time_limit: #时间超限
problem_info['time'] = time_now*1000
problem_info['memory'] = max_rss/1024.0
problem_info['result'] = "Time Limit Exceeded"
glan.terminate()
return problem_info
if max_rss > mem_limit: #内存超限
problem_info['time'] = time_now*1000
problem_info['memory'] = max_rss/1024.0
problem_info['result'] = "Memery Limit Exceeded"
problem_info['time'] = time_now*1000
problem_info['memory'] = max_rss/1024.0
problem_info['result'] = "next judge"
return problem_info
if __name__ == "__main__":
language = input("选择语言")
result = time_mem(language)
print(result)
(三)运行结果:
这里的待测试代码是:
#include <stdio.h>
int main()
{
int n,a;
scanf("%d",&n);
for(int i=1;i<=n;i++) printf("hello\n");
printf("一共有%d个hello\n",n);
for(int i=1;i<=3;i++){
scanf("%d",&a);
printf("%d",a);
}
return 0;
}
输入样例:
过程:
(四)代码详解:
p = subprocess.Popen(p_cmd[language],shell=True,cwd=dir_work, stdin=fin, stdout=fout, stderr=subprocess.PIPE) # cwd设置工作目录
Popen函数在第一篇文章中有过详细的介绍。这里的功能就是调用系统命令运行程序,stdin向程序中写入数据,stdout向相应文件中写入数据,stderr提供子进程的错误输出。注意stdin/stdout=不能用文件名,必须要使用相应的打开的可读或者可写的文件。p.pid还可以获取程序运行的进程号。
glan = psutil.Process(pid) #监听控制进程
m_infor = glan.memory_info()
psutil模块的使用:
使用详细教程:点击打开链接
关于linux进程占用的内存:
ps -aux 使用教程:点击打开链接
RSS:进程所占用的实际物理内存。