鱼C论坛

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

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

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

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

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

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

命令行调用方法:
monitor [可执行文件名]

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

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

如何实现?
最佳答案
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 [executable]" << std::endl;
        return 1;
    }

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

    if (!CreateProcess(NULL, argv[1], 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;
}

这段代码创建了一个新的进程,并在该进程退出后获取了运行时间、内存占用和返回值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 [executable]" << std::endl;
        return 1;
    }

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

    if (!CreateProcess(NULL, argv[1], 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;
}

这段代码创建了一个新的进程,并在该进程退出后获取了运行时间、内存占用和返回值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 [executable]" << std::endl;        return 1;    }    std::string executable = argv[1];    // 创建进程    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 的一些函数,包括 CreateProcessAWaitForSingleObjectGetExitCodeProcessGetProcessTimesGetProcessMemoryInfo。它通过调用 CreateProcessA 来启动指定的可执行文件,并等待进程结束。然后,它使用其他函数来获取进程的退出代码、使用时间和内存占用信息,并将结果输出到控制台。

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

希望这个解决方案对你有所帮助,如有其他问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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

如何实现?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

你可以使用Python的subprocess模块来实现这个功能。下面是一个示例代码,可以满足你的需求:
import subprocessimport timedef 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()[4].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[1]        # 监视程序    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官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

可不可以在程序结束之后得到程序内存最高占用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

当程序结束后,你不能直接从Python代码中获取程序的内存最高占用情况。但是,你可以借助第三方工具来实现这个功能,比如`psutil`模块。下面是一个示例代码,使用`psutil`模块来获取程序的内存最高占用情况:
import subprocessimport psutildef 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[1:]        # 监视程序    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官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 03:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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