文件映射IPC挂起MapViewOfFile调用

File mapping IPC hangs on MapViewOfFile call

本文关键字:MapViewOfFile 调用 挂起 IPC 映射 文件      更新时间:2023-10-16

我有一个遗留代码,它使用文件映射(幻灯片8-9)来执行IPC。但是,当通道的读写负载很高时,编写器线程会挂在MapViewOfFile上。MSDN没有关于MapViewOfFile的阻塞行为的信息。可能的原因是什么?

虽然整个源代码可以在github上找到,但代码的相关部分是

BOOL Channel::Read(LPVOID data, DWORD dataSize, BOOL response/* = FALSE*/)
{
    ::WaitForSingleObject(m_events[response 
                                   ? RESPONSE_AVAILABLE 
                                   : REQUEST_AVAILABLE], 
                          INFINITE);
    LPVOID source = ::MapViewOfFile(m_section, FILE_MAP_ALL_ACCESS, 0, 0, dataSize);
    if (!source) {
        if (!response) {
            ::SetEvent(m_events[SERVER_AVAILABLE]);
        }
        return FALSE;
    }
    ::CopyMemory(data, source, dataSize);
    BOOL ok = ::UnmapViewOfFile(source);
    if (!response) {
        ::SetEvent(m_events[SERVER_AVAILABLE]);
    }
    return ok;
}
BOOL Channel::Write(LPVOID data, DWORD dataSize, BOOL response/* = FALSE*/)
{
    if (!response) {
        ::WaitForSingleObject(m_events[SERVER_AVAILABLE], INFINITE);
    }
    LPVOID destination = ::MapViewOfFile(m_section, FILE_MAP_ALL_ACCESS, 0, 0, dataSize);
    if (!destination) {
        if(!response) {
            ::SetEvent(m_events[SERVER_AVAILABLE]);
        }
        return FALSE;
    }
    ::CopyMemory(destination, data, dataSize);
    if (::UnmapViewOfFile(destination)) {
        ::SetEvent(m_events[response 
                           ? RESPONSE_AVAILABLE 
                           : REQUEST_AVAILABLE]);
        return TRUE;
    } else {
        ::SetEvent(m_events[(response 
                             ? RESPONSE_AVAILABLE 
                             : SERVER_AVAILABLE)]);
        return FALSE;
    }
}

按照OP的建议,发布我的评论作为回答。

这种行为的一个可能原因是缺乏物理记忆。在这种情况下,MapViewOfFile必须交换一些内存,而且这个过程很耗时。当问题出现时,通过检查内存统计数据很容易验证这一假设。