OnlineJudge评测程序Python实现(三)Judge Time&Memory

本文介绍了一种利用Python的subprocess及psutil模块监控程序执行时间与内存的方法。通过调用外部命令执行程序,并实时获取进程信息,实现了对程序执行时间与内存使用的精确控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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:进程所占用的实际物理内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值