Rav*_*ngh 7 c# c++ visual-studio-2008 visual-studio
如何在C++中实现C#的lock关键字?c#中的代码如下:
try
{
lock (matrixLock)
{
ThisTransformation.get_Renamed(matrix);
}
}
Run Code Online (Sandbox Code Playgroud)
假设您有一个Mutex和一个Lock对象(您的里程可能会有所不同):
#define MY_OWN_LOCK(mm_mutex) \
\
if(bool b_1227F2B8_136B_11E1_973D_7D0B4924019B = false) \
; \
else \
for(Lock lock_1227F2B8_136B_11E1_973D_7D0B4924019B(mm_mutex); \
!b_1227F2B8_136B_11E1_973D_7D0B4924019B; \
b_1227F2B8_136B_11E1_973D_7D0B4924019B = true)
Run Code Online (Sandbox Code Playgroud)
可以用作:
Mutex mutex ;
void foo()
{
// not locked
MY_OWN_LOCK(mutex)
{
// locked
}
// not locked
}
Run Code Online (Sandbox Code Playgroud)
这取决于您将使用的库。
让我们假设你有:
Mutex对象,它有一个lock()和一个unlock()方法Lock对象,它有一个带Mutex参数的lock()构造函数,在构造时调用它的方法,unlock()在析构时调用它的方法所以,你有这样的事情:
class Mutex
{
public :
lock() ;
unlock() ;
// etc.
} ;
class Lock
{
Mutex & m_mutex ;
public :
Lock(Mutex & p_mutex) : m_mutex(p_mutex)
{ this->m_mutex.lock() ; }
~Lock()
{ this->m_mutex.unlock() ; }
// etc.
} ;
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉 C++ 的 RAII,您的代码将类似于:
void foo()
{
// not locked
mutex.lock() ;
// locked !
mutex.unlock() ;
// not locked
}
Run Code Online (Sandbox Code Playgroud)
这段代码太错误了,我永远不会讨论它(如果需要,谷歌“异常安全”)。
void foo()
{
// not locked
{
Lock lock(mutex) ;
// locked !
}
// not locked
}
Run Code Online (Sandbox Code Playgroud)
使用以下宏:
#define LOCK(mm_mutex) \
\
if(bool b = false) \
; \
else \
for(Lock lock(mm_mutex); !b; b = true)
Run Code Online (Sandbox Code Playgroud)
你将能够写:
void foo()
{
// not locked
LOCK(mutex)
{
// locked !
}
// not locked
}
Run Code Online (Sandbox Code Playgroud)
大多数锁宏依赖于锁对象是可测试的。这要么需要Safe Bool Idiom的实现(这对当前使用来说太过分了),要么需要将锁定对象强制转换为bool,这给类带来了自己的(大)缺陷集。
在当前的实现中,if用于声明将控制for的主体执行的布尔值,而for本身用于声明Lock对象本身。
我相信这种模式被称为“C++ 变量注入”。
请注意,你锁定的东西,所以里面的代码mutex.lock(),并mutex.unlock()会采取更多的周期比任何宏观。
在非优化构建中,将显示if和for跳转(例如,在可视化调试器上逐步尝试),但在优化构建中,整体if和for将被优化掉(“原始”生成的程序集之间没有区别C++ 使用”和“宏增强的 C++ 使用”。
出于教育目的,上面的宏被简化了。要在生产代码中使用它,您必须:
BOOST_一部分BOOST_FOREACH)b和 Locklock变量“唯一”以确保它们不会与用户代码发生冲突。我通常为此使用 GUID/UUID 后缀(例如b_ABCD_ABCD_AB_ABCDEF和lock_ABCD_ABCD_AB_ABCDEF)我第一次在一篇文章中看到了这种模式(我相信是 Andrei Alexandrescu 写的),事实上,当我偶然发现这个 SO 问题时,我正在寻找它。
:-)
找到来源后,我将使用正确的链接更新此答案。
编辑:找到来源!!!
这里有您需要的一切:Implementing a lock keywords in C++
C++ 没有 lock 关键字,但您可以自己创建一个。给定一个具有 Lock() 和 Unlock() 成员函数(为了方便起见可能还有 IsLocked())的 Mutex 类,大多数 C++ 程序员会立即编写一个 AutoLock,有点像这样:
class AutoLock
{
public:
AutoLock(Mutex& m): m_mutex(m) { m_mutex.Lock(); }
~AutoLock() { m_mutex.Unlock(); }
operator bool() { return m_mutex.IsLocked(); }
private:
Mutex& m_mutex;
};
Run Code Online (Sandbox Code Playgroud)
正常使用这个东西会是这样的:
{
AutoLock lock(m_mutex);
// my protected code here
}
Run Code Online (Sandbox Code Playgroud)
但通过简单的预处理器技巧,您可以使语法与 C# 相同:
#define lock(x) if (!(AutoLock _l = x)); else
Run Code Online (Sandbox Code Playgroud)