【问题标题】:Force first instance with compiler使用编译器强制第一个实例
【发布时间】:2014-01-01 12:27:46
【问题描述】:

我们已经创建了一个主存储堆内存管理器,它覆盖了new()delete() 运算符,但是存在一个问题,因为我们需要在发生任何其他内存分配之前启动内存管理器- 如果我们不这样做,那么该进程将包含一些非托管内存。到目前为止的解决方案是在具有main() 函数的同一文件中启动内存管理器,如下所示:

/*!
\brief Start the memory manager. 
\note It's important that this is causing the very first call to the overridden new() operator.
*/
CMemoryManager *g_memoryManager = CMemoryManager::Instance();

int main(int argc, char* argv[])
{
    // Code...
}

这可行但不是最优的,因为我们在每个可执行文件(如每个单元测试)中都需要它,因为内存管理器是一种横切关注类型的功能。对我们来说最理想的是将内存管理器启动放在单个库中并确保首先执行该库 - 因此我们不必将启动添加到每个可执行文件中。有没有办法用 G++、VC++ 和 ICC 编译器做到这一点?

/**
 * \defgroup MemoryManagerMutexes Uniform mutex definitions for use with the memory manager
 */
/*@{*/
#ifdef _WINDOWS
#define MM_INIT_CRITICAL_SECTION(arg1) InitializeCriticalSection(&arg1);
#define MM_DELETE_CRITICAL_SECTION(arg1) DeleteCriticalSection(&arg1);
#define MM_ENTER_CRITICAL_SECTION(arg1) EnterCriticalSection(&arg1);
#define MM_LEAVE_CRITICAL_SECTION(arg1) LeaveCriticalSection(&arg1);
#define MM_CRITICAL_SECTION_OBJECT(arg1) CRITICAL_SECTION arg1;
#else
#ifdef HAVE_PTHREAD_H
#define MM_INIT_CRITICAL_SECTION(arg1) pthread_mutex_init(&arg1, NULL);
#define MM_DELETE_CRITICAL_SECTION(arg1) pthread_mutex_destroy(&arg1);
#define MM_ENTER_CRITICAL_SECTION(arg1) pthread_mutex_lock(&arg1);
#define MM_LEAVE_CRITICAL_SECTION(arg1) pthread_mutex_unlock(&arg1);
#define MM_CRITICAL_SECTION_OBJECT(arg1) pthread_mutex_t arg1;
#else
#error Neither Windows nor POSIX mutex libraries were found and no fallback
#endif
#endif
/*@}*/

/*!
\brief Get the instance of the memory manager
\details Class uses a Singleton software design pattern
\returns The instance of the memory manager
*/
CMemoryManager *CMemoryManager::Instance()
{
    if (!instance)
    { 
        MM_INIT_CRITICAL_SECTION(mutex)
        instance = new CMemoryManager();
    }

    return instance;
}

// Non-TLS new() implementation
void *operator new(size_t size) 
{
    MM_ENTER_CRITICAL_SECTION(CMemoryManager::mutex)
    void *ret = CMemoryManager::Instance()->Malloc(size);
    MM_LEAVE_CRITICAL_SECTION(CMemoryManager::mutex)
return ret;
}

【问题讨论】:

  • 我认为您的意思是“实例化”而不是“启动” - 如果是这样,您应该进行编辑,以便标题准确地吸引人们。
  • @wilsonmichaelpatrick 已更改,谢谢。
  • 希望你没有超载全局new/delete
  • 如果尚未在您的new 中初始化管理器,您可以只初始化管理器吗?
  • 一个漂亮的计数器可以做到这一点:en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter

标签: c++ visual-c++ g++ icc


【解决方案1】:

在标题中更改您的实例例程

static Instance(bool first=false);

在定义中

CMemoryManager *CMemoryManager::Instance(bool first)
{
    if (!instance)
    {
        if (first)
       { 
            MM_INIT_CRITICAL_SECTION(mutex)
            instance = new CMemoryManager();
       }
       else
       {
           do {
               sleep(0);
           } while (!instance);
       }
    }

    return instance;
}

您将需要某种睡眠程序。 在主要

CMemoryManager *g_memoryManager = CMemoryManager::Instance(true);

【讨论】:

  • 我相信这可能会导致一些并发问题,因为instancefirst 不是原子变量。但是,如果它们是原子运算符变量,那么这可能会起作用,但我认为不需要 first
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
相关资源
最近更新 更多