在Windows上互斥,临界区等的成本

我在某处读到一个互斥量的开销并不多,因为上下文切换只发生在争用的情况下。

在Linux中也称为互斥体。

Windows中相同的东西是否保持良好? Critical Section是关于Linux中互斥体的更贴图。

从我所收集的内容来看,临界区与Mutex相比提供了更好的最佳性能,对于每一种情况都是如此?

在Windows中是否存在互斥体比临界区快的情况?

假设只有一个进程 – 线程正在访问互斥体(只是为了消除关键部分的其他好处)

补充信息:OS的Windows服务器,
语言C ++

考虑到Critical SectionsMutexes的具体目的,我不认为你可以问一个关于成本的问题,因为当你需要多个线程触摸相同的数据时,你没有太多的选择。 显然,如果你只需要增加/减少一个数字,你可以在一个volatile数字上使用Interlocked*()函数,这样你就可以继续工作了。 但是对于更复杂的任何事情,您都需要使用同步对象。

在Windows上可用的同步对象开始阅读。 所有的功能都列在那里,很好的分组和正确的解释。 有些只是Windows 8。

至于你的问题, Critical SectionsMutexe更便宜,因为它们被设计成在相同的过程中操作。 阅读这^和这^,或只是下面的报价。

临界区对象提供与由互斥对象提供的类似的同步,除了临界区只能由单个进程的线程使用。 事件,互斥体和信号量对象也可以在单进程应用程序中使用,但是关键节对象为互斥同步(特定于处理器的测试和设置指令)提供了一个更快,更高效的机制。 像互斥对象一样,临界区对象一次只能由一个线程拥有,这对保护共享资源免受同时访问很有用。 与互斥对象不同,无法判断临界区是否被放弃。

我使用Critical Sections进行同步进程同步和Mutexes进行跨进程同步。 只有当我真的需要知道一个同步对象是否被放弃时,我在同一个进程中使用了互斥锁。

所以,如果你需要一个同步对象,问题不是成本是多少,而是更便宜:)真的没有其他选择,但内存损坏。

PS :可能有其他选择,比如在这里选择的答案中提到的选项^,但我总是选择核心平台特定的功能与跨平台性。 它总是更快! 所以,如果你使用Windows,使用Windows的工具:)

UPDATE

根据您的需要,您可以通过尝试尽可能多地在线程中完成独立的工作来减少对同步对象的需求,并且只在最后或偶尔结合数据。

愚蠢的例子拿一个网址列表。 你需要刮他们并分析他们。

  1. 抛出一堆线程,并从输入列表中逐一挑选URL。 对于每一个你的过程你集中的结果,当你这样做。 这是真实的,很酷
  2. 或者你可以在每个线程中输入一个输入URL的片段。 这消除了同步选择过程的需要。 您将分析结果存储在线程中,最后将结果合并一次。 或者每10个网址就说一次。 不是每个人。 这将大大减少同步操作。

因此,通过选择合适的工具并考虑如何降低锁定和解锁,可以降低成本。 但成本不能被删除:)

PS :我只想在网址:)

更新2:

有一个项目需要做一些测量。 结果令人惊讶:

  • std::mutex是最昂贵的。 (跨平台的价格)
  • Windows本机Mutex量比std快两倍。
  • Critical Section本地Mutex快两倍。
  • SlimReadWriteLockCritical Section + -10%。
  • 我自制的InterlockedMutex (螺旋锁)Critical Section快了1.25x-1.75x。

在Windows 8上使用std :: mutex我通常使用我自己定制的自旋锁来获得3-4倍的改进(在非竞争情况下)加速:

基于互斥体

 auto time = TimeIt([&]() { for (int i = 0; i < tries; i++) { bool val = mutex.try_lock(); if (val) { data.value = 1; } } 

});

自制锁免费

 time = TimeIt([&]() { for (int i = 0; i < tries; i++) { if (!guard.exchange(true)) { // I own you data.value = 1; guard.store(true); } } }); 

测试是在x86上进行的。

我还没有想出什么std :: mutex在Windows上使用下划线,因为它会产生大量的代码。