我被任命来支持一些遗留代码,并且我看到了一些让我困惑的事情。在代码的某些部分中,我看到类实例使用 CMutex 实例来同步方法执行。例如,
class CClassA : public CObject
{
public:
void DoSomething();
private:
CMutex m_mutex;
}
void CClassA::DoSomething()
{
m_mutex.Lock();
//...logic...
m_mutex.Unlock();
}
在同一项目的其他地方,我发现代码
class CClassB : public CObject
{
public:
void DoSomething();
private:
CCriticalSection m_crit;
}
void CClassB::DoSomething()
{
CSingleLock lock(&m_crit);
lock.Lock();
//...logic...
lock.Unlock();
}
在查看 MSDN 同步文档,看来 CClassB 正在实现建议的方法,但我不清楚使用的实现有什么危险C类A。据我所知,这两种方法之间的唯一区别是 CSingleLock 具有 RAII 的优点,因此当执行退出作用域时,锁会自动释放。这两种实施方式还有其他优点/缺点吗?
I've been tapped to support some legacy code, and I'm seeing some things that cause me to scratch my head in confusion. In some sections of code, I see that a class instance uses a CMutex instance to synchronize method execution. For instance
class CClassA : public CObject
{
public:
void DoSomething();
private:
CMutex m_mutex;
}
void CClassA::DoSomething()
{
m_mutex.Lock();
//...logic...
m_mutex.Unlock();
}
Elsewhere in the same project I find that the code is using a CSingleLock
class CClassB : public CObject
{
public:
void DoSomething();
private:
CCriticalSection m_crit;
}
void CClassB::DoSomething()
{
CSingleLock lock(&m_crit);
lock.Lock();
//...logic...
lock.Unlock();
}
After reviewing MSDN documentation for synchronization, it would appear that CClassB is implementing the advised method, but it isn't clear to me what the danger is in the implementation used by CClassA. As far as I can tell, the only difference between the two methods is that CSingleLock has the benefit of RAII, so the lock is automatically released when execution exits scope. Are there any other benefits / drawbacks to either implementation?
发布评论
评论(2)
一般来说,互斥体可用于通过命名互斥体来控制跨进程的线程访问,而临界区仅用于同步同一进程空间中的线程访问。
如果不包装它们,这些类都不会真正获得 RAII 的好处,因为在这种情况下,您永远不需要显式调用 lock 或unlock。以使用 boost 互斥锁的这一点伪代码为例......
现在我认为你应该避免使用
CMutex
、CCritalSection
、CSemaphore
和CEvent
因为这些实现有些破损,或者至少不如其他可用的库(如 boost)。例如:CSingleLock
没有可重入锁,因此递归会导致问题。根据您的任务,您可能有机会放弃 Windows API 上的 MFC 包装器,并实现您自己的原子锁或使用 boost 或 C++0x 等功能,例如 < code>std::mutex 不仅是更好的实现,而且提供跨平台支持。
In general mutexes can be used to control thread access across processes via a named mutex while critical sections are only for synchronizing thread access in the same process space.
Neither of these classes truly get the benefit of RAII without wrapping them because in that case you would never need to explicitly call lock or unlock. Take for example this little bit of pseudo code using a boost mutex lock ...
Now I'd argue you should avoid
CMutex
,CCritalSection
,CSemaphore
, andCEvent
because the implementations are somewhat broken or at the very least inferior to other available libraries like boost. For example:CSingleLock
so recursion will cause issues.Depending on what you are tasked with you might have the opportunity to move away from the MFC wrappers on windows API and either implement your own atomic locks or use something like boost or C++0x features like
std::mutex
which not only are better implementations but provide cross-platform support.临界区仅对单个进程内的线程可见/可用。互斥体可以在多个进程中可见(通常通过创建命名互斥体)。您上面所显示的内容不足以说明这是否是他们同时拥有这两种情况的原因,但这是一种可能性。
A critical section is only visible to/usable by the threads inside a single process. A mutex can be made visible across a number of processes (typically by creating a named mutex). What you've shown above isn't enough to say whether this is why they have both, but it's one possibility.