在共享映像中管理内存的方式取决于特定平台,而 DLL 特定于 Microsoft Windows。
通常,您应该始终避免使用全局/共享静态变量,因为它们可能会引入难以识别或解决的严重问题或错误。即使是单例类也可能在 C++ 中引起一些问题,特别是在库或多线程应用程序中。(通常,即使在高级语言中,使用单例也不被认为是好的。)
为了防止互斥竞争条件,最好的选择是使用使用RAII 技术实现的作用域锁类,以及智能指针,它可以自动分配和取消分配内存。shared_ptr
下面的代码说明Mutex
了使用 Windows API 和上述技术(以及Pimpl idiom)实现:
// Mutex.h
#pragma once
#include <memory>
class Mutex
{
public:
typedef unsigned long milliseconds;
Mutex();
~Mutex();
void Lock();
void Unlock();
bool TryLock();
bool TimedLock(milliseconds ms);
private:
struct private_data;
std::shared_ptr<private_data> data;
// Actual data is hold in private_data struct which is non-accessible.
// We only hold a "copyable handle" to it through the shared_ptr, which
// prevents copying this "actual data" object by, say, assignment operators.
// So, private_data's destructor automatically gets called only when the last
// Mutex object leaves its scope.
};
// Mutex.cpp
#include "Mutex.h"
#include <windows.h>
struct Mutex::private_data
{
HANDLE hMutex;
private_data()
{
hMutex = CreateMutex(NULL, FALSE, NULL);
}
~private_data()
{
// Unlock(); ?? :/
CloseHandle(hMutex);
}
};
Mutex::Mutex()
: data (new private_data())
{ }
Mutex::~Mutex()
{ }
void Mutex::Lock()
{
DWORD ret = WaitForSingleObject(data->hMutex, INFINITE);
ASSERT(ret == WAIT_OBJECT_0);
}
void Mutex::Unlock()
{
ReleaseMutex(data->hMutex);
}
bool Mutex::TryLock()
{
DWORD ret = WaitForSingleObject(data->hMutex, 0);
ASSERT(ret != WAIT_ABANDONED);
ASSERT(ret != WAIT_FAILED);
return ret != WAIT_TIMEOUT;
}
bool Mutex::TimedLock(milliseconds ms)
{
DWORD ret = WaitForSingleObject(data->hMutex, static_cast<DWORD>(ms));
ASSERT(ret != WAIT_ABANDONED);
ASSERT(ret != WAIT_FAILED);
return ret != WAIT_TIMEOUT;
}
// ScopedLock.h
#pragma once
#include "Mutex.h"
class ScopedLock
{
private:
Mutex& m_mutex;
ScopedLock(ScopedLock const&); // disable copy constructor
ScopedLock& operator= (ScopedLock const&); // disable assignment operator
public:
ScopedLock(Mutex& mutex)
: m_mutex(mutex)
{ m_mutex.Lock(); }
~ScopedLock()
{ m_mutex.Unlock(); }
};
示例用法:
Mutex m1;
MyClass1 o1;
MyClass2 o2;
...
{
ScopedLock lock(m1);
// thread-safe operations
o1.Decrease();
o2.Increase();
} // lock is released automatically here upon leaving scope
// non-thread-safe operations
o1.Decrease();
o2.Increase();
虽然上面的代码会给你基本的想法,但更好的选择是使用高质量的 C++ 库,比如boost,它有mutex
,scoped_lock
以及许多其他已经可用的类。(幸运的是,C++11 完全覆盖了同步类,让您不必使用 boost 库。)
更新:
我建议您搜索有关 C++ 中的自动垃圾收集以及 RAII 技术的主题。