3

我知道在通过托管语言(如 C#、Java 等)在 Windows 机器上遇到上下文切换时,无法侦听、检测和执行某些操作。但是,我想知道是否有一种方法可以使用汇编(或其他一些语言,也许是 C)?如果是这样,您能否提供一个小代码片段来说明如何执行此操作(因为我对内核编程相对较新)?

这段代码本质上的设计目的是在标准 Windows UI 上的后台运行,并监听特定进程何时进入或退出 CPU 的上下文。在听到这些动作中的任何一个时,它都会发送一个信号。为了澄清,我只想检测直接涉及特定进程的上下文切换,而不是任何上下文切换。我最终想要实现的是能够在特定进程开始使用 CPU 以及停止使用 CPU 时通知另一台机器(通过互联网信号)。

我第一次尝试这样做只是简单地计算特定进程的 CPU 使用百分比,但最终证明这太粗略,无法捕捉到最细微的计算。例如,我编写了一个测试程序,它简单地执行了 2+2 操作并将答案放在一个 int 中。CPU 使用方法没有考虑到这一点。因此,我正在寻找较低级别的东西,因此是这个问题的起源。如果有潜在的替代品,我将非常乐意提供它们。

4

2 回答 2

4

Windows 事件跟踪 (ETW),您可以将其配置为接收有关系统中发生的各种事件的消息。

您应该能够接收有关线程调度事件的消息。CSwitch 类事件就是为此而生的。

抱歉,我不知道您可以轻松地为您的任务重复使用的任何好的 ETW 示例。阅读 MSDN 并环顾四周。

Simon指出了一个很好的链接,解释了为什么 ETW 有用。很有启发性:http ://randomascii.wordpress.com/2012/05/11/the-lost-xperf-documentationcpu-scheduling/

于 2012-09-25T22:03:17.243 回答
2

请参阅下面的编辑。特别是#3,ETW似乎是要走的路。

int 2Eh从理论上讲,您可以为旧的和新的安装自己的陷阱处理程序sysenter。然而,在实践中,由于 Patchguard(自 Vista 以来)和签名要求,这将不再像以前那样容易。我不知道检测上下文切换的任何其他通用方法,这意味着您必须自己动手。操作系统的所有上下文切换都通过调用门(前面提到的陷阱处理程序),如果您对调试/反汇编感到不舒服,ReactOS 允许您窥视幕后。

然而,在任何一种情况下,都不应该有一种通用的方法来安装这样的东西而没有内核模式特权(通常称为 ring 0)——其他任何东西都将是 Windows 中的安全漏洞。我也不知道 Windows 提供的方法来实现你想要的。

“Undocumented Windows NT”一书有一个关于确切主题的非常好的章节(尽管显然针对旧int 2Eh方法)。

如果您可以只挂钩某些功能,您可能能够摆脱一些过滤器驱动程序或用户模式 ​​API 挂钩。取决于您的具体要求。

更新:阅读您更新的问题,我认为您需要阅读内部,特别是 IRQL 的概念(不要与 DOS 时代的 IRQ 混淆)和调度程序。问题是每秒可以——而且通常会——进行数百次上下文切换。但是,您的观察者进程(监视上下文切换的那个)将像任何用户模式进程一样是可抢占的。这意味着您无法实现实时信令或任何接近它的东西,这对方法提出了一个很大的问号。

你真正想要达到的目标是什么?上下文切换的数量并没有真正给你任何东西。每个单独的 SEH 异常都会导致上下文切换。你对什么感兴趣?也许性能计数器可以更好地满足您的需求?

更新 2:即使对于单个线程,上下文切换的绝对数量也会在一秒钟内令人震惊。因此,假设您要安装自己的陷阱处理程序,您最终仍会(不利地)影响系统上的所有其他线程(毕竟您会捕获每个上下文切换,然后查看它是否是您关心的进程/线程和然后做你的事情或传递它)。

如果您可以告诉我们您最终想要实现的目标,而不是使用已经预先定义的方法,我们或许可以提出替代方案。

更新 3:显然我在这里的一个方面是错误的。Windows 自带了一些可以发出上下文切换信号的东西。并且可以利用 ETW 来利用这些。感谢西蒙指出。

于 2012-09-25T18:34:39.560 回答