简体   繁体   English

使用命名共享内存的 C++ 问题

[英]C++ Issues using Named Shared Memory

I've tried to implement a shared memory interface, however I am not able to get it working.我试图实现一个共享内存接口,但是我无法让它工作。

Since it isn't yet working I want to ask help.由于它尚未工作,我想寻求帮助。 A shared memory is necessary for my application which is an Multiobjective Evolutionary Algorithm that runs on several processes, however the various processes need to exchange information, and instead of dumping it into a physical file a billion times, I'd rather share memory using this method.我的应用程序需要共享内存,它是在多个进程上运行的多目标进化算法,但是各个进程需要交换信息,而不是将其转储到物理文件中十亿次,我宁愿使用它来共享内存方法。

I am on Win7x64 using C++ in VS v120.我在 VS v120 中使用 C++ 在 Win7x64 上。 For the sake of testing, all of this code takes place in the same process until I've figured it out.为了测试,所有这些代码都在同一个过程中进行,直到我弄清楚为止。

My filename is a const string我的文件名是一个常量字符串

 m_Filename = "Local\\shared_memory"

 m_BufferSize = 1024

EDIT 1:编辑 1:

So I see there is some confusion as to what I am trying to do here, well I am confused as well.所以我看到我在这里尝试做的事情有些混乱,我也很困惑。 Looking at the official documentation from MSDN it uses the file mapping with INVALID_HANDLE_VALUE , and they don't seem to create a file on disk.查看来自 MSDN 的官方文档,它使用带有INVALID_HANDLE_VALUE的文件映射,并且它们似乎没有在磁盘上创建文件。 This is fine for my solution.这对我的解决方案很好。 I don't need a file on disk, although either works.我不需要磁盘上的文件,尽管两者都可以。 The reason I tried to do it the other way is because the first method failed and I started searching, and I came across threads on here where people say that they need to make the actual file as well.我尝试以另一种方式做的原因是因为第一种方法失败了,我开始搜索,我在这里遇到了一些线程,人们说他们也需要制作实际文件。

This is a more complete code, and yes I do check the error codes.这是一个更完整的代码,是的,我确实检查了错误代码。

The m_Filename is set in the class constructor. m_Filename 在类构造函数中设置。 Buffer size is constant.缓冲区大小是恒定的。 I've removed my code which does the physical file stuff, I guess it isn't actually required?我已经删除了处理物理文件的代码,我想它实际上不是必需的?

    void MemoryMapper::_CreateMappedFile() {

    m_Handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
        0, m_BufferSize, m_Filename.c_str());

    if (m_Handle == NULL)
    {
        std::cout << m_DebugErrorTitle << "_CreateMappedFile(): " << MM_ERROR_CREATE_FAILED << 
            " (" << GetLastError() << ")" << std::endl;
        return;
    }

    m_pBuffer = (LPTSTR)MapViewOfFile(m_Handle, FILE_MAP_ALL_ACCESS, 0, 0, m_BufferSize);

    if (m_pBuffer == NULL)
    {
        std::cout << m_DebugErrorTitle << "_CreateMappedFile(): " << MM_ERROR_MAPPING_FAILED << 
            " (" << GetLastError() << ")" << std::endl;
        CloseHandle(m_Handle);
        return;
    }

    TCHAR szMsg[] = TEXT("Test message.");
    CopyMemory((PVOID)m_pBuffer, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));

    if (!UnmapViewOfFile(m_pBuffer)) {
        std::cout << m_DebugErrorTitle << "_CreateMappedFile(): UnmapViewOfFile() returned false. (" << GetLastError() << ")" << std::endl;
    }
    if (!CloseHandle(m_Handle)) {
        std::cout << m_DebugErrorTitle << "_CreateMappedFile(): CloseHandle() returned false. (" << GetLastError() << ")" << std::endl;
    }

    if (m_Debug > 1) { std::cout << m_DebugTitle << "Created mapped file: '" << m_Filename << "'." << std::endl; }
}

Running this code and I end up with the console message: [MemoryMapper] Created mapped file: 'Local\\shared_memory'.运行此代码,我最终得到控制台消息:[MemoryMapper] 创建的映射文件:'Local\\shared_memory'。

Then, in the same process, for the sake of testing??然后,在同样的过程中,为了测试?? I try to open the file again.我尝试再次打开该文件。 This time I get error code 2 saying the file doesn't exist.这次我收到错误代码 2,说该文件不存在。

bool MemoryMapper::_Open(const std::string& fn) {

    if (m_Debug > 2) { std::cout << m_DebugTitle << "Open '" << fn << "'." << std::endl; }

    m_OpenHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fn.c_str());

    if (m_OpenHandle == NULL)
    {
        std::cout << m_DebugErrorTitle << " _Open('" << fn << "'): " << MM_ERROR_OPEN_FAILED << " (" << GetLastError() << ")" << std::endl;
        m_IsOpen = false;
        return m_IsOpen;
    }
    m_IsOpen = true;
    if (m_Debug > 1) { std::cout << m_DebugTitle << "Open: " << std::to_string(m_IsOpen) << std::endl; }
    return m_IsOpen;
}

The filename is the same.文件名是一样的。 100%. 100%。

Why can't I open the file?为什么我打不开文件?

Also, should I be checking if a shared memory object exists with the set filename before creating one?另外,在创建共享内存对象之前,我是否应该检查是否存在具有设置文件名的共享内存对象? Does the object get cleared away when the application terminates?应用程序终止时对象是否被清除?

EDIT 2:编辑2:

It seems that the handle given from the initial CreateFileMapping() must remain open for the duration I want to use the shared object?似乎从初始 CreateFileMapping() 给出的句柄必须在我想使用共享对象的持续时间内保持打开状态?

I attempted this and now it seems to work fine.我尝试了这个,现在它似乎工作正常。 I can make the object, open it, write and close it using separate calls.我可以使用单独的调用创建对象、打开它、写入和关闭它。 My mistake was closing the handle upon creation, although, which is correct?我的错误是在创建时关闭了句柄,但是,哪个是正确的?

first of all, if you tried to implement a shared memory interface - for what you create file on disk ?首先,如果您尝试实现共享内存接口 - 您在磁盘上创建文件的目的是什么? you can do this, but it absolute not need in this case你可以这样做,但在这种情况下绝对不需要

(3) Now the object in itself should exist in memory, no? (3) 现在对象本身应该存在于内存中,不是吗?

now object really exist in NT-namespace but until you not close last handle to it.现在对象确实存在于 NT 命名空间中,但直到您没有关闭它的最后一个句柄。 when last handle is closed, object name is removed from NT-namespace, unless you not use OBJ_PERMANENT flag in OBJECT_ATTRIBUTES .当最后一个句柄关闭时,对象名称将从 NT 命名空间中删除,除非您不在OBJECT_ATTRIBUTES使用OBJ_PERMANENT标志。 but for this need use NtCreateSection instead CreateFileMapping and have SE_CREATE_PERMANENT_PRIVILEGE但为此需要使用NtCreateSection而不是CreateFileMapping并具有SE_CREATE_PERMANENT_PRIVILEGE

if OpenFileMapping fail with error ERROR_FILE_NOT_FOUND this mean that name, which you using in call, not exist in NT Namespace.如果OpenFileMapping失败并出现错误ERROR_FILE_NOT_FOUND这意味着您在调用中使用的名称在 NT 命名空间中不存在。 this can be by several reasons: - the process, which call OpenFileMapping run under another terminal session ( Local\\shared_memory is expanded to \\Sessions\\<SessionId>\\BaseNamedObjects\\shared_memory or to \\BaseNamedObjects\\shared_memory if you run it from session 0).这可能是由于以下几个原因: - 调用OpenFileMapping的进程在另一个终端会话下运行(如果从会话 0 运行,则Local\\shared_memory扩展为\\Sessions\\<SessionId>\\BaseNamedObjects\\shared_memory\\BaseNamedObjects\\shared_memory ) . you can simply mistake with name.你可以简单地误用名称。

but faster of all - you close section handle, returned by CreateFileMapping before you call OpenFileMapping .但更快 - 您关闭部分句柄,在调用OpenFileMapping之前由CreateFileMapping返回。 because you not use OBJ_PERMANENT object name deleted when all open handles to them are closed.因为您没有使用OBJ_PERMANENT对象名称删除它们的所有打开句柄都已关闭。 object itself can continue exist if exist references to it - say when you call MapViewOfFile - you create reference to section - and it will be not deleted until you not unmap it, but section name will be removed anyway, when all open handles to them are closed.如果存在对它的引用,则对象本身可以继续存在 - 例如,当您调用MapViewOfFile - 您创建对节的引用 - 并且在您不取消映射之前不会删除它,但是无论如何都会删除节名称,当所有打开的句柄都为它们时关闭。


how i and assume at begin - OpenFileMapping fail because section no more exist at time which it called.我如何在开始时假设 - OpenFileMapping失败,因为在它调用的时间段不再存在。 it handles already closed.它处理已经关闭。 void MemoryMapper::_CreateMappedFile() by fact do nothing - this function create temporary object, do some manipulations with it and destroy at exit. void MemoryMapper::_CreateMappedFile()实际上什么都不做——这个函数创建临时对象,用它做一些操作并在退出时销毁。 all this have no any affect after function return所有这些在函数返回后都没有任何影响

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM