我之前从未真正使用过互斥锁,但我需要控制对受保护资源的访问。看看新的C ++ 11的东西,我把这个课堂搞定了:
class CMutex
{
public:
class Lockable
{
friend class CMutex;
std::atomic_flag flag;
public:
Lockable()
{
flag.clear();
}
};
private:
Lockable * resource;
CMutex(const CMutex &);
public:
CMutex(Lockable * l)
{
resource = l;
acquire(l);
}
CMutex(Lockable & l)
{
resource = &l;
acquire(l);
}
CMutex()
: resource(nullptr)
{
}
~CMutex()
{
if (resource)
release(resource);
}
void acquire(Lockable * l)
{
if (!resource)
resource = l;
if (!spinLock(2000, resource))
//explode here
return;
}
void acquire(Lockable & l)
{
acquire(&l);
}
private:
void release(Lockable * l)
{
if (l)
l->flag.clear();
}
static bool spinLock(int ms, Lockable * bVal)
{
using namespace Misc;
long start;
int ret;
loop:
start = QuickTime();
while (bVal->flag.test_and_set()) {
if ((QuickTime() - start) > ms)
goto time_out;
// yield thread
Delay(0);
}
// normal exitpoint
return true;
// deadlock occurs
time_out:
// handle error ...
}
}
这样的用法:
class MyClass : public CMutex::lockable
{
...
void doStuff()
{
// lock data
CMutex(this);
// do stuff
...
// mutex should automagically be RAII released here
}
...
};
首先,我感兴趣的是这个概念是否真的有效(给定std :: atomic等的实现)?
其次,我注意到它正确获得了锁,但是它立即释放了。我想我应该给锁一个名字?
CMutex lock(this);
但是,在将作用域保留为优化之前,编译器是否可以自由地破坏对象,前提是它可以保证我不会与对象进行更多交互?如果我不能保证只在范围出口处调用析构函数,那么这将破坏这个构造的目的。
此致
答案 0 :(得分:1)
不,编译器在作用域结束之前无法自由销毁。
根据C ++标准第12.4 / 10节 - 对于创建对象的块退出时具有自动存储持续时间(3.7.3)的构造对象。
答案 1 :(得分:-1)
这是一个可能对您有用的技巧,适用于所有主流(VC ++,clang,gcc)编译器:
#define APPEND_ID1(id1, id2) id1##id2
#define APPEND_ID2(id1, id2) APPEND_ID1(id1, id2)
#define APPEND_COUNTER(id) APPEND_ID2(id, __COUNTER__)
#define SCOPED_LOCK(lockable) CMutex APPEND_COUNTER(scoped_lock)(lockable)
class MyClass : public CMutex::lockable
{
...
void doStuff()
{
// lock data
SCOPED_LOCK(this);
// auto-generates a unique name, works even with multiple locks in the same scope..
SCOPED_LOCK(that);
// do stuff
...
// mutex should automagically be RAII released here
}