鱼C论坛

 找回密码
 立即注册
查看: 2968|回复: 6

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

[复制链接]
发表于 2023-11-13 16:18:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

命令行调用方法:


  1. monitor [可执行文件名]
复制代码


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

例如:


  1. C:\Users\Default> monitor a.exe
  2. time: 0.013
  3. memory: 768KB
  4. return code: 0
复制代码


如何实现?
最佳答案
2023-11-13 16:18:46
你可以使用Windows API函数来实现获取程序的运行状态。你可以使用GetProcessTimes函数来获取程序的运行时间,使用GetProcessMemoryInfo函数来获取程序的内存占用情况,使用GetExitCodeProcess函数来获取程序的返回值。

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

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

  3. int main(int argc, char* argv[])
  4. {
  5.     if (argc < 2)
  6.     {
  7.         std::cout << "Usage: monitor [executable]" << std::endl;
  8.         return 1;
  9.     }

  10.     PROCESS_INFORMATION pi;
  11.     STARTUPINFO si;
  12.     ZeroMemory(&si, sizeof(si));
  13.     si.cb = sizeof(si);

  14.     if (!CreateProcess(NULL, argv[1], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  15.     {
  16.         std::cerr << "Failed to create process" << std::endl;
  17.         return 1;
  18.     }

  19.     WaitForSingleObject(pi.hProcess, INFINITE);

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

  27.         std::cout << "time: " << userSeconds << std::endl;
  28.     }

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

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

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

  41.     return 0;
  42. }
复制代码


这段代码创建了一个新的进程,并在该进程退出后获取了运行时间、内存占用和返回值。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-13 16:18:46 | 显示全部楼层    本楼为最佳答案   
你可以使用Windows API函数来实现获取程序的运行状态。你可以使用GetProcessTimes函数来获取程序的运行时间,使用GetProcessMemoryInfo函数来获取程序的内存占用情况,使用GetExitCodeProcess函数来获取程序的返回值。

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

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

  3. int main(int argc, char* argv[])
  4. {
  5.     if (argc < 2)
  6.     {
  7.         std::cout << "Usage: monitor [executable]" << std::endl;
  8.         return 1;
  9.     }

  10.     PROCESS_INFORMATION pi;
  11.     STARTUPINFO si;
  12.     ZeroMemory(&si, sizeof(si));
  13.     si.cb = sizeof(si);

  14.     if (!CreateProcess(NULL, argv[1], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  15.     {
  16.         std::cerr << "Failed to create process" << std::endl;
  17.         return 1;
  18.     }

  19.     WaitForSingleObject(pi.hProcess, INFINITE);

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

  27.         std::cout << "time: " << userSeconds << std::endl;
  28.     }

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

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

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

  41.     return 0;
  42. }
复制代码


这段代码创建了一个新的进程,并在该进程退出后获取了运行时间、内存占用和返回值。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-13 16:20:20 | 显示全部楼层
要实现这个功能,你可以使用 Windows API 提供的相关函数来获取进程的信息。以下是一个可能的解决方案:
  1. #include <Windows.h>
  2. #include <iostream>
  3. #include <string>
  4. int main(int argc, char* argv[])
  5. {
  6.     if (argc != 2)
  7.     {
  8.         std::cout << "Usage: monitor [executable]" << std::endl;
  9.         return 1;
  10.     }
  11.     std::string executable = argv[1];
  12.     // 创建进程
  13.     STARTUPINFOA startupInfo;
  14.     PROCESS_INFORMATION processInfo;
  15.     ZeroMemory(&startupInfo, sizeof(startupInfo));
  16.     ZeroMemory(&processInfo, sizeof(processInfo));
  17.     if (!CreateProcessA(NULL, const_cast<char*>(executable.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
  18.     {
  19.         std::cout << "Failed to start the process." << std::endl;
  20.         return 1;
  21.     }
  22.     // 等待进程结束
  23.     WaitForSingleObject(processInfo.hProcess, INFINITE);
  24.     // 获取进程退出代码
  25.     DWORD exitCode;
  26.     GetExitCodeProcess(processInfo.hProcess, &exitCode);
  27.     // 获取进程使用时间
  28.     FILETIME creationTime, exitTime, kernelTime, userTime;
  29.     GetProcessTimes(processInfo.hProcess, &creationTime, &exitTime, &kernelTime, &userTime);
  30.     ULARGE_INTEGER startTime, endTime;
  31.     startTime.LowPart = creationTime.dwLowDateTime;
  32.     startTime.HighPart = creationTime.dwHighDateTime;
  33.     endTime.LowPart = exitTime.dwLowDateTime;
  34.     endTime.HighPart = exitTime.dwHighDateTime;
  35.     double elapsedTime = (endTime.QuadPart - startTime.QuadPart) / 10000.0;
  36.     // 获取进程内存信息
  37.     PROCESS_MEMORY_COUNTERS_EX memoryCounters;
  38.     GetProcessMemoryInfo(processInfo.hProcess, (PROCESS_MEMORY_COUNTERS*)&memoryCounters, sizeof(memoryCounters));
  39.     SIZE_T memoryUsage = memoryCounters.WorkingSetSize;
  40.     // 输出结果
  41.     std::cout << "time: " << elapsedTime << " ms" << std::endl;
  42.     std::cout << "memory: " << memoryUsage / 1024 << "KB" << std::endl;
  43.     std::cout << "return code: " << exitCode << std::endl;
  44.     // 清理资源
  45.     CloseHandle(processInfo.hProcess);
  46.     CloseHandle(processInfo.hThread);
  47.     return 0;
  48. }
复制代码

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

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

希望这个解决方案对你有所帮助,如有其他问题,请随时提问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-30 09:31:22 | 显示全部楼层
@FishC_GPT

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

命令行调用方法:


  1. monitor [可执行文件名]
复制代码


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

例如:


  1. C:\Users\Default> monitor a.exe
  2. time: 0.013
  3. memory: 768KB
  4. return code: 0
复制代码


如何实现?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-30 09:31:46 | 显示全部楼层
zhangjinxuan 发表于 2023-11-30 09:31
@FishC_GPT

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

你可以使用Python的subprocess模块来实现这个功能。下面是一个示例代码,可以满足你的需求:
  1. import subprocess
  2. import time
  3. def monitor_program(executable):
  4.     # 启动子进程,并设置stdout、stderr和stdin为PIPE
  5.     process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
  6.    
  7.     # 开始时间
  8.     start_time = time.time()
  9.    
  10.     while True:
  11.         # 判断子进程是否已经结束
  12.         if process.poll() is not None:
  13.             break
  14.         
  15.         # 每隔0.1秒获取一次子进程的内存占用情况
  16.         memory_usage = subprocess.check_output(['tasklist', '/FI', 'PID eq ' + str(process.pid)])
  17.         
  18.         # 打印内存占用情况
  19.         print('memory:', memory_usage.split()[4].decode(), 'K')
  20.         
  21.         # 等待0.1秒
  22.         time.sleep(0.1)
  23.    
  24.     # 结束时间
  25.     end_time = time.time()
  26.    
  27.     # 获取子进程的返回值
  28.     return_code = process.returncode
  29.    
  30.     # 打印运行时间和返回值
  31.     print('time:', round(end_time - start_time, 3))
  32.     print('return code:', return_code)
  33. if __name__ == '__main__':
  34.     import sys
  35.    
  36.     # 获取命令行参数中的可执行文件名
  37.     executable = sys.argv[1]
  38.    
  39.     # 监视程序
  40.     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官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

可不可以在程序结束之后得到程序内存最高占用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-30 09:36:01 | 显示全部楼层
zhangjinxuan 发表于 2023-11-30 09:35
可不可以在程序结束之后得到程序内存最高占用

当程序结束后,你不能直接从Python代码中获取程序的内存最高占用情况。但是,你可以借助第三方工具来实现这个功能,比如`psutil`模块。下面是一个示例代码,使用`psutil`模块来获取程序的内存最高占用情况:
  1. import subprocess
  2. import psutil
  3. def monitor_program(executable):
  4.     # 启动子进程,并设置stdout、stderr和stdin为PIPE
  5.     process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
  6.    
  7.     # 等待子进程结束
  8.     process.wait()
  9.    
  10.     # 获取子进程的PID
  11.     pid = process.pid
  12.    
  13.     # 获取子进程的内存使用情况
  14.     memory_info = psutil.Process(pid).memory_full_info()
  15.    
  16.     # 打印内存最高占用情况
  17.     print('peak memory usage:', memory_info.peak_wset / 1024, 'KB')
  18. if __name__ == '__main__':
  19.     import sys
  20.    
  21.     # 获取命令行参数中的可执行文件名
  22.     executable = sys.argv[1:]
  23.    
  24.     # 监视程序
  25.     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官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-21 14:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表