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

时间:2016-01-04 12:29:22

标签: c++ multithreading winapi ipc

我有一个遗留代码,它使用文件映射(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;
    }
}

1 个答案:

答案 0 :(得分:1)

根据OP的建议,将我的评论作为答案发布。

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