当前进程的性能计数器的竞争条件

Posted

技术标签:

【中文标题】当前进程的性能计数器的竞争条件【英文标题】:Race condition with Performance Counters for current process 【发布时间】:2011-09-28 14:30:44 【问题描述】:

我正在尝试解决旧的“How do I get a Windows Performance Counter for the current process”问题。基本上,我是 enumerating Process Object instances 来获取 Process 对象的列表,然后我可以查询它们的进程 ID 并与我自己的进行比较。

基于此,我可以使用正确的实例索引(以创建类似于\Process(my_program#3)\<counter> 的内容)构建性能计数器路径,然后我可以使用它来查询我感兴趣的任何计数器。但是如果一个会发生什么或更多其他 my_program 实例在 PdhAddCounter 调用之前退出?如果我理解正确,这意味着我的计数器路径现在指的是不同的进程或者现在无效。它们甚至可能在查询进程 ID 时消失...

如何防止计数器路径失效,然后才能使用它来获取计数器句柄?

【问题讨论】:

我很确定现有计数器的路径不会改变。实例可能会来来去去并最终回收标识符(以及路径),但只要您的实例存在,我很确定它将具有相同的标识符(以及路径)。如果不是这样,我会感到震惊。 @Luke:不幸的是,路径确实变得无效。这很容易证明,当另一个实例已经启动时,在调试器中打开程序,然后单步执行以允许程序确定正确的实例(#1),然后手动关闭第一个实例,然后再次单步执行以允许查询计数器的程序 - 它们不起作用。 【参考方案1】:

哇,你是对的。这对我来说似乎是一个主要的设计缺陷。如果实例的名称不是唯一的,则基本上不可能可靠地监视实例。我确实偶然发现了一个专门针对 Process 和 Thread 对象的workaround,但这是一个可能影响其他应用程序的全局设置。

我认为最安全的方法是监视所有进程对象,并且每次收集数据时都通过并找到具有所需进程 ID 的对象。

【讨论】:

该解决方法可能会影响其他应用程序,因此不会像您自己指出的那样运行。监控所有流程会有帮助吗?据我所知,没有办法将打开的计数器映射到它所属的进程。 我认为你不能用 PdhAddCounter 做到这一点。也许您可以使用注册表接口为所有进程收集多个计数器;在这种情况下,我相信计数器将为每个对象按顺序存储,您可以从那里找出来。不过,我可能是错的;我正在从我最近实施的提供者的角度考虑这个问题。从未编写过消费者代码。 MSDN 声明:“您不应使用注册表函数来使用计数器数据。” 这是建议,而不是强制要求。 PDH API 使用起来更简单,但注册表 API 功能更强大,但代价是难度和繁琐。

以上是关于当前进程的性能计数器的竞争条件的主要内容,如果未能解决你的问题,请参考以下文章

跨应用域回收使用自定义性能计数器

linux 性能调优

获取 C 中的进程性能计数器

所有同名进程的性能计数器?

windows下使用性能计数器遇到的坑

性能计数器实例名称与进程名称