首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++应用程序中安全地生成内存映射文件

在C++应用程序中安全地生成内存映射文件
EN

Stack Overflow用户
提问于 2013-03-08 13:56:26
回答 1查看 1.1K关注 0票数 3

我有一个古老的C++应用程序,最初构建于Visual 6.0中,它使用一个非常复杂的共享内存DLL在大约8个EXE和DLL之间共享数据,它们都有一个值池,可以用一个或两个字典替换,其中字符串作为键,记录用于值。该应用程序是多线程和多进程.有三个主可执行文件读取和写入共享内存区域,其中几个可执行文件中有3个或多个线程可以在这个池内存区域中读取/写入或“队列”信息。大约几百个位置,__try__except的结构化异常处理(SEH)用于过滤异常,并试图通过调整共享内存的大小来处理访问冲突,共享内存位于一个名为CGMMF的类管理的段中,这意味着可增长内存映射文件。

这里显示了最突出的细节,因为我找不到任何关于正在使用的技术的有凝聚力的文档来源,或者它的安全性和适用性。从实验上我发现,这个库在1998年的单个核心系统上工作得不太好,在运行windows XP的单核虚拟机上工作得不太好,而且在2013年,它在现代2+ ghz多核Windows 7 64位系统上根本不能工作。我在试着修理或者更换它。

代码语言:javascript
复制
#define ResAddrSpace(pvAddress, dwSize)  \
   (m_hFileMapRes = CreateFileMapping(HFILE_PAGEFILE, &m_SecAttr,             \
      PAGE_READWRITE| SEC_RESERVE, 0, dwSize, m_szRegionName),                    \
   (m_hFileMapRes == NULL) ? NULL :                                     \
      MapViewOfFileEx(m_hFileMapRes, FILE_MAP_ALL_ACCESS, 0, 0, dwSize, 0))


void CGmmf::Create(void)
{
    DWORD dwMaxRgnSize;
    if (Gsinf.dwAllocationGranularity == 0) 
    {
        GetSystemInfo(&Gsinf);
    }
    m_dwFileSizeMax = RoundUp(m_dwFileSizeMax, Gsinf.dwAllocationGranularity);
    m_dwFileGrowInc = RoundUp(m_dwFileGrowInc, Gsinf.dwAllocationGranularity);
    dwMaxRgnSize = m_dwFileSizeMax + m_dwOverrunBuf;
    m_pbFile = (PBYTE)ResAddrSpace(NULL, dwMaxRgnSize);
        Adjust(m_dwFileSizeNow);
}

void CGmmf::Adjust(IN DWORD dwDiskFileNow) 
{
    int nThreadPriority;

    __try 
    {
        //
        // Boost our thread's priority so that another thread is 
        // less likely to use the same address space while 
        //  we're changing it.
        //
        nThreadPriority = GetThreadPriority(GetCurrentThread());
        SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

        //
        // Restore the contents with the properly adjusted lengths
        //
        Construct(dwDiskFileNow);
    }
    __finally 
    {       
        //
        // Make sure that we always restore our priority class and thread 
        // priority so that we do not continue to adversely affect other 
        // threads in the system.
        //

        SetThreadPriority(GetCurrentThread(), nThreadPriority);
    }
}


void CGmmf::Construct(IN DWORD dwDiskFileNow) 
{
    DWORD dwDiskFileNew = RoundUp(dwDiskFileNow, m_dwFileGrowInc),
          dwStatus = ERROR_SUCCESS;

    PBYTE pbTemp;

    if (dwDiskFileNew > 0) 
    {
        //
        // Grow the MMF by creating a new file-mapping object.
        //
            // use VirtualAlloc() here to commit
        // the requested memory: VirtualAlloc will not fail
        // even if the memory block is already committed:

        pbTemp = (PBYTE)VirtualAlloc(m_pbFile,dwDiskFileNew,MEM_COMMIT,PAGE_READWRITE);

        if(NULL == pbTemp)
        {
            LogError(GetLastError(), MEM_CREATE_MMF, m_szRegionName);

            // 
            //  File-mapping could not be created, the disk is 
            //  probably full.
            //
            RaiseException(EXCEPTION_GMMF_DISKFULL, 
                           EXCEPTION_NONCONTINUABLE, 
                           0, 
                           NULL);
        }

        // 
        //  Check to see if our region has been corrupted 
        //  by another thread.
        //
        if (pbTemp != m_pbFile)
        {
            RaiseException(EXCEPTION_GMMF_CORRUPTEDRGN, 
                           EXCEPTION_NONCONTINUABLE, 
                           0, 
                           NULL);
        }
    }
}

到目前为止,我替换它的选项包括尝试将所有共享内存替换为DCOM (离开进程COM)和COM (在process中),以适合内存映射文件的位置,并使用同步/互斥/关键部分或其他线程安全结构(酌情使用同步/互斥/关键部分或其他线程安全结构)手动防止并发问题。

我想知道是否已经存在一些线程安全的内存字典类型,我可以用它来替换所有这些。即使在上面的代码片段中,这个古老的共享内存库用于可视化C++-6的代码还不到1%,有些事情让我不寒而栗。例如,将线程优先级提高为避免死锁、竞争条件和一般损坏的策略。也许这曾经使这段代码在33 mhz的80486 CPU上停止了大量的崩溃。战栗。

我已经在VisualVISUAL6.0中构建和运行了代码,并且它的一个分支运行在VisualC++ 2008中,我可能会在VisualC++ 2010中运行它。我能用什么来给我字典语义,跨进程共享内存,并且是稳定和可靠的?

更新的“字典”--我指的是在C++中已知的字典数据类型,它在某些地方也被称为“键/值存储”,而在其他地方(如C++标准库中),它被称为std::map。讨论这是这里。的Boost文档

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-08 14:05:46

听起来你应该看看Boost进程间。您可以使用它在共享内存中使用std::map-like对象,等等。自从我上次使用它已经有很多年了,所以不能详细介绍,但是库文档很好,有大量的例子,它应该可以让您在30分钟内完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15295579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档