为了在Windows操作系统上进行性能监视,我需要一个可以报告任意进程的用户和内核时间的程序。在POSIX系统上,标准time
实用程序完全可以,因为它可以报告挂钟时间,用户时间和内核时间。
对于Windows,默认情况下没有此类实用程序。我环顾四周,发现至少有三种选择。正如我在下面解释的那样,它们都不适合我的需要。
timeit
(无法回想起确切的版本)。它不再分布,支持或保证在现代系统上工作。我无法测试它。time
。与具有类似输出格式的POSIX对应项几乎完全相同。timep.exe
,可在source code和二进制文件中找到他的书“Windows System Programming,4th Edition”。这是一个非常简单的实用程序,它使用WinAPI的GetProcessTimes()
来获取完全相同的三个值。我怀疑Cygwin的time
在这方面没有什么不同。现在问题是:GetProcessTimes()
仅报告由timep
直接生成的PID的时间,但不是其子项。这使得time
和timep
对我来说毫无用处。
我的目标EXE应用程序通常是通过BAT文件生成的,该文件再调用一个BAT文件;两个BAT都用于调整环境或更改命令行参数:
timep.exe
|
+---wrapper.bat
|
+--- real-wrapper.bat
|
+--- application.exe
单独wrapper.bat
报告的时间对application.exe
一无所知。
显然,POSIX(fork-exec)和Win32(CreateProcess)的进程创建模型非常不同,这使得我的目标很难在Windows上实现。
我想尝试编写自己的time
变体。它必须递归地总结给定过程及其所有孩子,孙子等的时间。到目前为止,我可以想象以下方法:
CreateProcess()
并获取其PID(根PID )并处理;将此句柄添加到列表GetProcessTimes()
并总结这个算法很糟糕,因为它很活泼 - 子进程可能在任何进程的生命后期创建,或者它们可以在我们有机会获得它们的句柄之前终止。在这两种情况下,报告的结果时间都是不正确的。
我的问题是:有更好的解决方案吗?
编辑:我可以使用Job Objects实现目标。下面是从我的应用程序中提取的代码片段,与从进程及其所有子进程获取内核和用户时间相关。希望它可以节省一些时间。
我使用Windows 8.1 x64和VS 2015进行了测试,但它应该可以向后移植到至少Windows 7.对于{{1},32位主机(我不确定)可能需要一些小问题。 } types - 我不熟悉CL.EXE在这些平台上处理它们的方法。
long long
答案 0 :(得分:4)
是的,从timep.exe创建一个作业,然后使用job accounting。子进程(除非在自己的作业中创建)与其父进程共享作业。
这几乎会跳过你的步骤2-4
答案 1 :(得分:0)
我已将此问题的解决方案打包到一个名为chronos的Windows独立程序中。它创建一个作业对象,然后在其中生成一个请求的进程。之后产生的所有孩子都留在同一个工作对象中,因此可以在以后计算。