【问题标题】:What is the performance of boost::interprocess_mutex vs Win32 native mutexes?boost::interprocess_mutex 与 Win32 本机互斥锁的性能如何?
【发布时间】:2009-07-22 15:55:28
【问题描述】:

请注意,我可以在 boost 源代码中进行研究,如果没有人提供答案,我可能会这样做来回答我自己的好奇心。

我确实问了,因为也许有人已经做过这个比较并且可以权威地回答?

似乎在进程之间创建共享内存映射文件,并通过使用InterlockedIncrement() 进行构造,可以创建类似于CRITICAL_SECTION 的主要用户模式互斥锁,这将比用于进程间同步的Win32 Mutex 性能要高得多.

所以我的期望是,boost::interprocess_mutex 的 Win32 上的实现可能会以这种方式实现,并且比原生 API 提供的速度要快得多。

不过我只有一个假设,通过现场测试不知道boost::interprocess_mutex的进程间同步性能如何,或者深入研究了它的实现。

是否有人在使用它或分析其相对性能方面有经验,或者他们可以评论在使用共享内存的进程之间使用 InterlockedIncrement() 的安全性吗?

【问题讨论】:

  • 如果我理解你的问题,你似乎在问关键部分比互斥锁更有效(答案是肯定的)。如果我理解有误,请改写您的问题。
  • 不能在两个进程之间的共享内存中创建临界区,因此它不是进程间同步的候选机制。
  • @Neil - 带上你的 cmets。

标签: c++ windows winapi boost synchronization


【解决方案1】:

在 boost 1.39.0 中,只有对 pthread 的特定支持。在所有其他平台上,它变成了一个繁忙的循环,中间有一个 yield 调用(基本上与您描述的系统相同)。请参阅 boost/interprocess/sync/emulation/interprocess_mutex.hpp。例如,这里是lock()的实现:

inline void interprocess_mutex::lock(void)
{
   do{
      boost::uint32_t prev_s = detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);

      if (m_s == 1 && prev_s == 0){
            break;
      }
      // relinquish current timeslice
      detail::thread_yield();
   }while (true);
}

这意味着,Windows 上的争用 boost::interprocess::mutex 非常昂贵——尽管非争用情况几乎是免费的。这可以通过添加一个事件对象或类似的睡眠来改善,但这不适合 boost::interprocess 的 API,因为没有地方可以放置访问互斥锁所需的每个进程的 HANDLE。

【讨论】:

  • 进程本地存储是 malloc() 或 new :)
【解决方案2】:

似乎在进程之间创建共享内存映射文件,并通过使用 InterlockedIncrement() 进行构造,可以创建类似于 CRITICAL_SECTION 的主要用户模式互斥锁,这将比 Win32 Mutex 用于进程间同步的性能要高得多。

CRITICAL_SECTION 在内部可以在发生争用时使用同步原语。我忘了它是事件、信号量还是互斥量。

您可以“安全地”在内存上使用Interlocked 函数,因此没有理由不能将它用于跨进程同步,除此之外,这真的很疯狂,您可能应该使用线程或真正的同步原语。

But officially, you can.

【讨论】:

  • 这也是我所相信的,我只是找不到太多关于在 Windows 上使用互锁增量进行进程间同步的知识。 boost 暗示它做到了。这可能是一个稍微模糊的问题,因为共享内存不是 Win32 平台上经常使用的技术,因为线程框架的普及和开发专业知识。
  • msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx 在 The Interlocked API 下第一段的最后一句中,它说您可以将它们用于跨进程的共享内存。
  • "如果变量在共享内存中,不同进程的线程可以使用这些函数。"看得很清楚,谢谢。 :) 我想知道是否有人在他们的实现中使用过这个工具?
  • 这种实现的一个问题是您需要手动处理终止的进程。即,一个进程锁定了一个共享互斥体,由于错误而终止——互斥体保持锁定状态。由于操作系统现在不再处理这个问题,互斥锁将永远保持锁定状态——所以也需要存储所有者等。我真的很安全的实施是很多工作。 Boost.Interprocess 在 Win32 上不提供此类功能。
  • 不开玩笑。这就是为什么您最好使用 win32 互斥锁而不是自己滚动的原因。无论如何,任何“高性能”跨进程通信都不太可能是高性能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 2012-07-04
  • 2011-07-22
  • 2010-12-07
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
相关资源
最近更新 更多