c++ - 在用户模式和内核之间使用共享内存进行慢速通信
问题描述
我在 Windows 内核中运行一个线程,通过共享内存与应用程序通信。一切工作正常,除了由于睡眠循环而导致通信缓慢。我一直在研究自旋锁、互斥锁和互锁,但无法真正弄清楚这一点。我也考虑过 Windows 事件,但不知道那个事件的性能。请建议什么是更快的解决方案,通过共享内存保持通信可能暗示 Windows 事件。
内核代码
typedef struct _SHARED_MEMORY
{
BOOLEAN mutex;
CHAR data[BUFFER_SIZE];
} SHARED_MEMORY, *PSHARED_MEMORY;
ZwCreateSection(...)
ZwMapViewOfSection(...)
while (TRUE) {
if (((PSHARED_MEMORY)SharedSection)->mutex == TRUE) {
//... do work...
((PSHARED_MEMORY)SharedSection)->mutex = FALSE;
}
KeDelayExecutionThread(KernelMode, FALSE, &PollingInterval);
}
应用代码
OpenFileMapping(...)
MapViewOfFile(...)
...
RtlCopyMemory(&SM->data, WriteData, Size);
SM->mutex = TRUE;
while (SM->mutex != FALSE) {
Sleep(1); // Slow and removing it will cause an infinite loop
}
RtlCopyMemory(ReadData, &SM->data, Size);
更新 1 目前这是我想出的最快的解决方案:
while(InterlockedCompareExchange(&SM->mutex, FALSE, FALSE));
但是,我觉得很有趣,您需要进行交换并且没有仅用于比较的功能。
解决方案
您不想使用 InterlockedCompareExchange。它会消耗 CPU,使共享该物理内核的另一个线程可能需要的内核资源饱和,并且可以使内核间总线饱和。
你确实需要做两件事:
1)编写一个InterlockedGet
函数并使用它。
2) 防止循环消耗 CPU 资源,并在最终解除阻塞时占用所有错误预测分支的母亲。
对于 1,众所周知,这适用于所有支持 . 的编译器,InterlockedCompareExchange
至少在我上次检查时:
__inline static int InterlockedGet(int *val)
{
return *((volatile int *)val);
}
对于 2,将其作为等待循环的主体:
__asm
{
rep nop
}
对于 x86 CPU,这是为了解决资源饱和和分支预测问题而指定的。
把它放在一起:
while ((*(volatile int *) &SM->mutex) != FALSE) {
__asm
{
rep nop
}
}
int
如果不合适,请根据需要进行更改。
推荐阅读
- c++ - 为什么在 asio 的示例中,tcp 接受器模式使用 shared_pointer 模型包装堆套接字,而 udp 使用堆栈套接字?
- javascript - 将 vue-qrcode 编译成 razorlight 和 dinktopdf
- php - 分块显示大数据 - PHP
- angular - 延迟加载存在问题。我在子路由方面遇到了一些问题
- angular - 仅在以角度刷新页面后才会显示来自 api 的数据
- java - wifip2pManager.discoverPeers() 在 ANDROID 10 中失败,尽管使用了运行时权限并且也在清单中
- python - 如何在 2 个模型之间找到相似的预测 x?
- java - Amazon S3 Select 问题:不支持在字段内发生换行符
- java - 为什么我需要一个独立的存储库的片段接口?
- javascript - java: 包 netscape.javascript 不存在,尽管已将 plugin.jar 添加到类路径