如何在C ++中实现C#的lock关键字? c#中的代码如下:
try
{
lock (matrixLock)
{
ThisTransformation.get_Renamed(matrix);
}
}
答案 0 :(得分:4)
假设您有一个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)
可以用作:
Mutex mutex ;
void foo()
{
// not locked
MY_OWN_LOCK(mutex)
{
// locked
}
// not locked
}
这取决于您将使用的库。
我们假设你有:
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.
} ;
如果您不熟悉C ++的RAII,您的代码将如下:
void foo()
{
// not locked
mutex.lock() ;
// locked !
mutex.unlock() ;
// not locked
}
这段代码是错的,我不会讨论它(谷歌“异常安全”,如果需要的话)。
void foo()
{
// not locked
{
Lock lock(mutex) ;
// locked !
}
// not locked
}
使用以下宏:
#define LOCK(mm_mutex) \
\
if(bool b = false) \
; \
else \
for(Lock lock(mm_mutex); !b; b = true)
你可以写:
void foo()
{
// not locked
LOCK(mutex)
{
// locked !
}
// not locked
}
大多数锁定宏依赖于锁定对象是可测试的。这需要Safe Bool Idiom的实现(对于当前使用来说是过度杀伤),或者需要将锁定对象转换为bool
,这会带来自己的(大)缺陷集上课。
在当前实现中,if
用于声明控制for
正文执行的布尔值,而for
本身用于声明{{1}对象本身。
我相信这种模式被称为“C ++变量注入”。
请注意,您正在锁定某些内容,因此Lock
和mutex.lock()
中的代码将比宏中的任何内容占用更多周期。
在非优化版本中,mutex.unlock()
和if
跳转将显示(例如,在可视化调试器上逐步尝试),但在优化构建中,整个{{1} }和for
将被优化掉(“原始C ++使用”和“宏增强C ++使用”生成的程序集之间没有区别。
上面的宏被简化用于教育目的。要在生产代码中使用它,您必须:
if
宏的for
部分)BOOST_
和锁定BOOST_FOREACH
变量“唯一”以确保它们不会与用户代码发生冲突。我通常使用GUID / UUID后缀(例如b
和lock
)我第一次在文章中看到了这种模式(我相信安德烈亚历山大夫斯库),事实上,当我偶然发现这个问题时,我正在寻找它。
: - )
一旦找到来源,我就会用正确的链接更新这个答案。
编辑:找到源!!!
答案 1 :(得分:3)
您可以使用boost::mutex
和boost::scoped_lock
:
boost::mutex matrix_mutex;
// ...
try {
boost::scoped_lock lock(matrix_mutex);
// ... everything in this scope is now locked
} // ....
您可以使用宏和for循环为您提供lock
关键字,但我强烈建议您不要这样做,因为这会破坏恰好使用lock
作为标识符的代码。< / p>
答案 2 :(得分:3)
C#lock
关键字不是互斥锁。相反,它会调用Monitor::Enter()
试试这个。另请查看MSDN reference。
// Request the lock, and block until it is obtained.
Monitor::Enter(m_inputQueue);
try
{
// Write your code here.
}
finally
{
// Ensure that the lock is released.
Monitor::Exit(m_inputQueue);
}
注意:此答案假定您的目标是C ++ CLI。
答案 3 :(得分:1)
以下是您需要的一切:Implementing a lock keyword in C++
C ++没有lock关键字,但您可以自己创建一个。给定一个具有Lock()和Unlock()成员函数的Mutex类(为方便起见可能是一个IsLocked()),大多数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;
};
这件事的正常使用看起来像这样:
{
AutoLock lock(m_mutex);
// my protected code here
}
但是使用简单的预处理器技巧,您可以使语法与C#相同:
#define lock(x) if (!(AutoLock _l = x)); else
答案 4 :(得分:1)
C ++没有lock关键字。你可以use a mutex。
答案 5 :(得分:1)
你不能,不存在这样的关键词,你得到的最接近的东西是boost scoped lock(可以使用提升互斥锁)。
答案 6 :(得分:1)
我会使用Boost synchronization library。如果由于某些原因你不能,我会这样做:
class CriticalSection {
CRITICAL_SECTION m_cs;
public:
CriticalSection() {
::InitializeCriticalSection(&m_cs);
}
~CriticalSection() {
::DeleteCriticalSection(&m_cs);
}
void Lock() {
::EnterCriticalSection(&m_cs);
}
void Unlock() {
::LeaveCriticalSection(&m_cs);
}
};
class CriticalSectionLocker {
CriticalSection& m_cs;
bool m_bLocked;
public:
CriticalSectionLocker(CriticalSection& cs, bool bLockNow = true) : m_cs(cs), m_bLocked(bLockNow) {
if(bLockNow)
m_cs.Lock();
}
~CriticalSectionLocker() {
if(m_bLocked)
m_cs.Unlock();
}
void Lock() {
m_cs.Lock();
m_bLocked = true;
}
void Unlock() {
m_cs.Unlock();
m_bLocked = false;
}
};
Caveat Emptor:此代码未通过编译器传递。 YMMV。
此代码允许您执行以下操作:
class SomeClass {
CriticalSection m_cs;
SomeResource m_resource;
public:
void SomeOperation() {
CriticalSectionLocker lock(m_cs);
m_resource.DoSomething();
}
};
锁被锁定在SomeClass::SomeOperation()
的范围内。如果您不再需要保持锁定,也可以通过调用Unlock()
方法释放锁定。
此代码绝不是一般化的。它可以用模板很棒来整理,并使其足够通用以使用互斥锁和其他操作系统对象。但是如果想去那里,我建议改用boost库。
答案 7 :(得分:0)
您可以使用std::lock_guard
这是该文档中的简化示例:
std::mutex resource_mutex;
...
{
std::lock_guard<std::mutex> lock(resource_mutex); // The variable name ("lock") doesn't matter since it is not supposed to be used anywhere else.
...
// safe to use resource here
...
}