内存在共享映像中的管理方式取决于特定的平台,并且DLL是特定于Microsoft Windows的。
一般来说,你应该总是避免使用全局/共享静态变量,因为它们可能会引入严重的问题或错误,这些错误是难以识别或解决。即使是单例类也可能导致several issues in C++,特别是在库或多线程应用程序中。 (通常,采用单身are not considered good即使在更高层次的语言。)
对于防范互斥竞争条件,最好的办法是使用范围的锁类使用RAII technique实现的,旁边的shared_ptr
smart pointer,它会自动内存分配和解除分配。
在下面的代码说明了通过使用Windows API和上述技术实现Mutex
(以及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();
虽然上面的代码将会给你的基本理念,甚至是更好的选择是使用像boost高品质的C++库,其中有已经上市mutex
, scoped_lock
和许多其他类。 (幸运的是C++ 11完全覆盖了同步类,使您不必使用boost库。)
更新:
我建议你搜索有关C++自动垃圾收集以及RAII技术的主题。
动态加载库不是C++标准的一部分,因此在运行时加载库的操作语义必须由平台指定。 –