c++ - 用户模式和内核之间使用共享内存的缓慢通信

标签 c++ windows kernel mutex spinlock

我在 Windows 内核中运行一个线程,通过共享内存与应用程序通信。除了由于 sleep 循环导致通信速度变慢外,一切正常。我一直在研究自旋锁、互斥锁和互锁锁,但无法真正弄清楚这一点。我也考虑过 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++ - 用户模式和内核之间使用共享内存的缓慢通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55016251/

相关文章:

c++ Friend函数不被识别为具有模板特化的 friend

c++ - 从下拉框中选择不同的项目时更改选项卡小部件的 currentIndex()

mysql - 如果为 NULL,则返回零

c - 如何调用文件操作的读函数的正确方法?

c - 使用 sk_buff 添加以太网帧头

c++ - 这个 operator< 语法是什么?

c++ - 模板函数中的 volatile 类型推导有什么问题?

c++ - 如何为 Win32 构建谷歌的 C++ libphonenumber 库

windows - 如何将以 "!"结尾的参数传递给另一个bat文件?

Android insmod内核对象在启动时