首页 > 解决方案 > 如何在 ubuntu 的 php 脚本中获取程序(c、c++、java、python、php)的执行时间和内存使用情况?

问题描述

我正在尝试使用带有 laravel 的 php 构建一个在线法官网站,该网站可以判断用户提交的代码是否存在问题。服务器环境是ubuntu。

每个问题都有一个输入文件和相应的输出文件以及代码的最大执行时间限制和内存使用限制。

假设对于一个问题,输入文件是 input.in,输出文件是正确的.out。裁判会运行用户的代码并生成输出文件并与correct.out进行比较,以检查解决方案是否正确。它还将检查代码是否在给定的时间限制和内存限制内运行。

允许用户使用 c、c++、java、python 或 php 提交他们的解决方案

我做了什么:

对于 c++ 代码,假设用户的代码是 code.cpp。我在我的 php 脚本中使用了 exec(),如下所示:

exec('g++ -o code code.cpp');

这将创建一个名为“code”的可执行文件。

现在,我已经使用 input.in 文件运行了可执行文件,并使用以下命令生成了 output.out 文件:

exec('./code < input.in > output.out');

这给出了输出文件。

现在我需要知道程序执行了多少时间,以及它使用了多少内存来运行或声明代码中的变量、数组或其他数据结构。

我可以通过计算执行的开始时间和结束时间之间的差异来找到执行时间。

我的问题是:

标签: phpc++ubuntug++shell-exec

解决方案


你回答:

  1. 我认为没有更好的方法可以直接测量exec运行时间。

  2. Profiler 是唯一的方法 ( valgrind)。但是,分析器会影响性能(它会大大降低性能)。当进程仍在运行时,您可以通过以下命令检查其内存使用情况:

    grep VmPeak /proc/$PID/status

精度会很差,对于类似的快速过程,echo你甚至可以没有时间运行这个 shell 命令。

  1. 检查退出代码(来自g++./code)以检查错误。保证对于g++自定义程序,它可能有自定义逻辑并使用自己的协议来报告错误,但通常如果./code遵循惯例,它必须在错误时将退出代码设置为非零。

但是,一般来说,并不能保证理解程序是否正确运行,因为“正确”是关于语义而不是纯粹的编码。“正确”是软件作者希望它工作的方式。如果软件作者认为软件必须以特定代码退出,他可以独立于任何内部错误进行操作。

例如,请参阅此代码:

#include <iostream>
#include <cstdlib>

int main()
{
    int z = 1;
    int y = 1;
    int x = 1 / (z - y);
    return 0;
}

它生成“除以零”异常。

让我们编译并执行它:

$ g++ program_1.cpp -o program_1
$ ./program_1
Floating point exception (core dumped)
$ echo $?
136

程序以代码退出136;原因是 C 运行时实现的默认除以零信号处理程序与此代码一起退出。

如果我们添加自己的信号处理程序,退出代码仍然是0

#include <iostream>
#include <cstdlib>

#include <sys/types.h>
#include <signal.h>

void signal_handler (int signo) 
{
    if(signo == SIGFPE) 
        exit(0);
}

int main()
{
    signal(SIGFPE,(*signal_handler));
    int z = 1;
    int y = 1;
    int x = 1 / (z - y);
    return 0;
}

因此,当您运行完全未知的外部代码时,几乎不可能理解它的真正作用;例如,这就是病毒的工作方式,它们的行为方式与您预期的不同。


推荐阅读