zhangjinxuan 发表于 2023-11-13 16:18:32

C++如何获得一个程序的运行状态(例如占用内存,使用时间,返回值)

我想要实现一个 C++ 程序,这个程序可以实现运行另一个程序,并且监视这个程序的占用内存,使用时间,返回值,系统环境为 Windows。

命令行调用方法:


monitor [可执行文件名]


期望输出这个可执行文件的占用内存,使用时间,返回值。

例如:


C:\Users\Default> monitor a.exe
time: 0.013
memory: 768KB
return code: 0


如何实现?

isdkz 发表于 2023-11-13 16:18:46

你可以使用Windows API函数来实现获取程序的运行状态。你可以使用GetProcessTimes函数来获取程序的运行时间,使用GetProcessMemoryInfo函数来获取程序的内存占用情况,使用GetExitCodeProcess函数来获取程序的返回值。

以下是一个简单的示例代码:

#include <windows.h>
#include <iostream>

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
      std::cout << "Usage: monitor " << std::endl;
      return 1;
    }

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);

    if (!CreateProcess(NULL, argv, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    {
      std::cerr << "Failed to create process" << std::endl;
      return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);

    FILETIME createTime, exitTime, kernelTime, userTime;
    if (GetProcessTimes(pi.hProcess, &createTime, &exitTime, &kernelTime, &userTime))
    {
      ULARGE_INTEGER time;
      time.LowPart = userTime.dwLowDateTime;
      time.HighPart = userTime.dwHighDateTime;
      double userSeconds = time.QuadPart / 10000000.0;

      std::cout << "time: " << userSeconds << std::endl;
    }

    PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(pi.hProcess, &pmc, sizeof(pmc)))
    {
      std::cout << "memory: " << pmc.WorkingSetSize / 1024 << "KB" << std::endl;
    }

    DWORD exitCode;
    if (GetExitCodeProcess(pi.hProcess, &exitCode))
    {
      std::cout << "return code: " << exitCode << std::endl;
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}


这段代码创建了一个新的进程,并在该进程退出后获取了运行时间、内存占用和返回值。

Mike_python小 发表于 2023-11-13 16:20:20

要实现这个功能,你可以使用 Windows API 提供的相关函数来获取进程的信息。以下是一个可能的解决方案:


#include <Windows.h>
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
      std::cout << "Usage: monitor " << std::endl;
      return 1;
    }

    std::string executable = argv;

    // 创建进程
    STARTUPINFOA startupInfo;
    PROCESS_INFORMATION processInfo;
    ZeroMemory(&startupInfo, sizeof(startupInfo));
    ZeroMemory(&processInfo, sizeof(processInfo));
    if (!CreateProcessA(NULL, const_cast<char*>(executable.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
    {
      std::cout << "Failed to start the process." << std::endl;
      return 1;
    }

    // 等待进程结束
    WaitForSingleObject(processInfo.hProcess, INFINITE);

    // 获取进程退出代码
    DWORD exitCode;
    GetExitCodeProcess(processInfo.hProcess, &exitCode);

    // 获取进程使用时间
    FILETIME creationTime, exitTime, kernelTime, userTime;
    GetProcessTimes(processInfo.hProcess, &creationTime, &exitTime, &kernelTime, &userTime);
    ULARGE_INTEGER startTime, endTime;
    startTime.LowPart = creationTime.dwLowDateTime;
    startTime.HighPart = creationTime.dwHighDateTime;
    endTime.LowPart = exitTime.dwLowDateTime;
    endTime.HighPart = exitTime.dwHighDateTime;
    double elapsedTime = (endTime.QuadPart - startTime.QuadPart) / 10000.0;

    // 获取进程内存信息
    PROCESS_MEMORY_COUNTERS_EX memoryCounters;
    GetProcessMemoryInfo(processInfo.hProcess, (PROCESS_MEMORY_COUNTERS*)&memoryCounters, sizeof(memoryCounters));
    SIZE_T memoryUsage = memoryCounters.WorkingSetSize;

    // 输出结果
    std::cout << "time: " << elapsedTime << " ms" << std::endl;
    std::cout << "memory: " << memoryUsage / 1024 << "KB" << std::endl;
    std::cout << "return code: " << exitCode << std::endl;

    // 清理资源
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);

    return 0;
}


这个程序使用了 Windows API 的一些函数,包括 CreateProcessA、WaitForSingleObject、GetExitCodeProcess、GetProcessTimes 和 GetProcessMemoryInfo。它通过调用 CreateProcessA 来启动指定的可执行文件,并等待进程结束。然后,它使用其他函数来获取进程的退出代码、使用时间和内存占用信息,并将结果输出到控制台。

你可以将上述代码保存为名为 monitor.cpp 的源文件,并使用 C++ 编译器进行编译。然后,在命令行中使用 monitor 命令来运行你的程序并监视另一个可执行文件的运行状态。

希望这个解决方案对你有所帮助,如有其他问题,请随时提问。

zhangjinxuan 发表于 2023-11-30 09:31:22

@FishC_GPT

我想要实现一个 Python 程序,这个程序可以实现运行另一个程序,并且监视这个程序的占用内存,使用时间,返回值,系统环境为 Windows。

命令行调用方法:


monitor [可执行文件名]


期望输出这个可执行文件的占用内存,使用时间,返回值。

例如:


C:\Users\Default> monitor a.exe
time: 0.013
memory: 768KB
return code: 0


如何实现?

FishC_GPT 发表于 2023-11-30 09:31:46

zhangjinxuan 发表于 2023-11-30 09:31
@FishC_GPT

我想要实现一个 Python 程序,这个程序 ...

你可以使用Python的subprocess模块来实现这个功能。下面是一个示例代码,可以满足你的需求:

import subprocess
import time

def monitor_program(executable):
    # 启动子进程,并设置stdout、stderr和stdin为PIPE
    process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
   
    # 开始时间
    start_time = time.time()
   
    while True:
      # 判断子进程是否已经结束
      if process.poll() is not None:
            break
      
      # 每隔0.1秒获取一次子进程的内存占用情况
      memory_usage = subprocess.check_output(['tasklist', '/FI', 'PID eq ' + str(process.pid)])
      
      # 打印内存占用情况
      print('memory:', memory_usage.split().decode(), 'K')
      
      # 等待0.1秒
      time.sleep(0.1)
   
    # 结束时间
    end_time = time.time()
   
    # 获取子进程的返回值
    return_code = process.returncode
   
    # 打印运行时间和返回值
    print('time:', round(end_time - start_time, 3))
    print('return code:', return_code)

if __name__ == '__main__':
    import sys
   
    # 获取命令行参数中的可执行文件名
    executable = sys.argv
   
    # 监视程序
    monitor_program(executable)

在这个示例代码中,我们使用`subprocess.Popen`函数启动了一个子进程,并通过`stdout=subprocess.PIPE`、`stderr=subprocess.PIPE`和`stdin=subprocess.PIPE`将其输出、错误和输入都重定向到了管道中。

然后,我们使用`tasklist`命令获取子进程的内存占用情况,并通过`subprocess.check_output`函数将结果存储在`memory_usage`变量中。

在循环中,我们每隔0.1秒打印一次子进程的内存占用情况,直到子进程结束。

最后,我们通过`process.returncode`获取子进程的返回值,使用`time.time`计算运行时间,并将其打印出来。

你可以在命令行中使用`python monitor.py a.exe`来运行这个程序,其中monitor.py是上述代码所保存的文件名,a.exe是要监视的可执行文件的路径。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

zhangjinxuan 发表于 2023-11-30 09:35:44

FishC_GPT 发表于 2023-11-30 09:31
你可以使用Python的subprocess模块来实现这个功能。下面是一个示例代码,可以满足你的需求:



可不可以在程序结束之后得到程序内存最高占用

FishC_GPT 发表于 2023-11-30 09:36:01

zhangjinxuan 发表于 2023-11-30 09:35
可不可以在程序结束之后得到程序内存最高占用

当程序结束后,你不能直接从Python代码中获取程序的内存最高占用情况。但是,你可以借助第三方工具来实现这个功能,比如`psutil`模块。下面是一个示例代码,使用`psutil`模块来获取程序的内存最高占用情况:
import subprocess
import psutil

def monitor_program(executable):
    # 启动子进程,并设置stdout、stderr和stdin为PIPE
    process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
   
    # 等待子进程结束
    process.wait()
   
    # 获取子进程的PID
    pid = process.pid
   
    # 获取子进程的内存使用情况
    memory_info = psutil.Process(pid).memory_full_info()
   
    # 打印内存最高占用情况
    print('peak memory usage:', memory_info.peak_wset / 1024, 'KB')

if __name__ == '__main__':
    import sys
   
    # 获取命令行参数中的可执行文件名
    executable = sys.argv
   
    # 监视程序
    monitor_program(executable)
在这个示例代码中,我们使用`psutil.Process`函数来获取子进程的内存使用情况,其中`pid`是子进程的进程ID。然后,我们通过`memory_info.peak_wset`属性获取内存的最高占用情况,单位为字节。最后,我们将其转换为KB并打印出来。你可以在命令行中使用`python monitor.py a.exe`来运行这个程序,其中monitor.py是上述代码所保存的文件名,a.exe是要监视的可执行文件的路径。请注意,在使用`psutil`模块之前,你需要先安装它。可以使用`pip install psutil`命令来安装。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: C++如何获得一个程序的运行状态(例如占用内存,使用时间,返回值)