文件映射 IPC 在 MapViewOfFile 调用上挂起

Posted

技术标签:

【中文标题】文件映射 IPC 在 MapViewOfFile 调用上挂起【英文标题】:File mapping IPC hangs on MapViewOfFile call 【发布时间】:2016-01-04 12:29:21 【问题描述】:

我有一个使用文件映射 (slides 8-9) 进行 IPC 的旧代码。但是当通过通道进行高负载读写时,写入器线程会挂在MapViewOfFile上。 MSDN 没有关于MapViewOfFile 的阻塞行为的信息。可能的原因是什么?

虽然整个源代码可能是found on 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;
    

【问题讨论】:

如果对MapViewOfFile 的调用无限期挂起,您可以创建转储文件(例如使用任务管理器)以供以后分析。然后可以使用 WinDbg 的 !locks 命令来识别正在等待的同步对象。 太丑了,扔掉它,改用命名管道。 @HansPassant 可能是我听过的最好的推荐。我很想扔掉 OpenForge 的全部源代码(Aviro 杀毒软件甚至将其后代检测为危险应用程序)。 一个可能的原因是交换 - 如果内存不足,MapViewOfFile 将交换出内存。您确定在此期间您有足够的物理内存吗? @SergeyA 看起来就是这样。问题很可能出现在 QA 的 VM 上,而不是开发人员机器上。明天我会进一步检查。你会这么好心把这个作为答案发布吗? :) 【参考方案1】:

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

此行为的一个可能原因是物理内存不足。在这种情况下 MapViewOfFile 必须换出一些内存,这个过程非常耗时。当问题出现时,通过检查内存统计信息很容易验证这个假设。

【讨论】:

以上是关于文件映射 IPC 在 MapViewOfFile 调用上挂起的主要内容,如果未能解决你的问题,请参考以下文章

Windows 64 和 32 位可以使用 MapViewOfFile 映射的最大文件大小

CreateFileMapping,MapViewOfFile,处理泄漏 C++

MapViewOfFile 与线程之间的指针

调用 MapViewOfFile 时出错

IPC瓶颈?

Windows API一日一练(59)CreateFileMapping和MapViewOfFile函数