CMutex::Lock 与 CSingleLock::Lock

发布于 2024-11-08 11:57:02 字数 828 浏览 4 评论 0 原文

我被任命来支持一些遗留代码,并且我看到了一些让我困惑的事情。在代码的某些部分中,我看到类实例使用 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桃气十足 2024-11-15 11:57:02

一般来说,互斥体可用于通过命名互斥体来控制跨进程的线程访问,而临界区仅用于同步同一进程空间中的线程访问。

如果不包装它们,这些类都不会真正获得 RAII 的好处,因为在这种情况下,您永远不需要显式调用 lock 或unlock。以使用 boost 互斥锁的这一点伪代码为例......

void DoSomething()
{
  // construction acquires lock on mutex
  boost::scoped_lock lock(&aBoostMutex);

  // ...

} // end scope - object is destroyed and lock is released

现在我认为你应该避免使用 CMutexCCritalSectionCSemaphoreCEvent 因为这些实现有些破损,或者至少不如其他可用的库(如 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 ...

void DoSomething()
{
  // construction acquires lock on mutex
  boost::scoped_lock lock(&aBoostMutex);

  // ...

} // end scope - object is destroyed and lock is released

Now I'd argue you should avoid CMutex, CCritalSection, CSemaphore, and CEvent because the implementations are somewhat broken or at the very least inferior to other available libraries like boost. For example:

  • Determining between a timeout from an abandoned mutex is impossible because the implementation checks return value only not the reason.
  • No reentrant locks using CSingleLock so recursion will cause issues.
  • Inability to have a named event between processes

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.

温柔少女心 2024-11-15 11:57:02

临界区仅对单个进程内的线程可见/可用。互斥体可以在多个进程中可见(通常通过创建命名互斥体)。您上面所显示的内容不足以说明这是否是他们同时拥有这两种情况的原因,但这是一种可能性。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文