Windows上的互斥锁,关键部分等的成本

Des*_*Ice 8 c++ windows multithreading mutex critical-section

我在某处读到互斥锁的开销并不是那么多,因为上下文切换仅在争用的情况下发生.

在Linux中也称为Futexes.

在Windows中,同样的事情是否有用?Critical Section是一个更适合Linux中互斥体的映射.

从我收集的内容来看,与Mutex相比,Critical Sections提供了更好的最佳性能,这是否适用于所有情况?

是否有一个角落案例,其中互斥体比Windows中的关键部分更快.

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

添加信息:OS Windows Server,
语言C++

Cod*_*gry 12

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

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

至于你的问题,Critical Sections它们比Mutexes 更便宜,因为它们被设计为在同一个过程中运行.阅读这个^这个^或只是以下引用.

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

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

所以,如果你需要一个同步对象,问题不是什么是成本,而是更便宜:)除了内存损坏之外别无选择.

PS:可能有像这里选择的答案中提到的那样的替代品^但我总是寻求核心平台特定功能与跨平台性.它总是更快!因此,如果您使用Windows,请使用Windows的工具:)

UPDATE

根据您的需要,您可以通过尝试在线程中尽可能多地执行自包含工作来减少对同步对象的需求,并且只在最后或之后组合数据.

愚蠢的例子:获取一个URL列表.你需要刮掉它们并进行分析.

  1. 扔进一堆线程,然后从输入列表中逐个选择URL.对于每个过程,您都可以在执行过程时集中结果.这是实时和酷
  2. 或者你可以抛出每个拥有输入URL片段的线程.这消除了同步选择过程的需要.将分析结果存储在线程中,最后只将结果合并一次.或者每10个网址就说一次.不适合他们每个人.这将大大减少同步操作.

因此,通过选择合适的工具并考虑如何降低锁定和解锁,可以降低成本.但成本无法消除:)

PS:我只想在URL :)

更新2:

是否需要在一个项目中做一些测量.结果非常令人惊讶:

  • A std::mutex是最贵的.(跨平台价格)
  • 一个Windows自带Mutex的2倍的速度比std.
  • A Critical Section比本Mutex快2倍.
  • A SlimReadWriteLock是+的10%Critical Section.
  • 我的自制InterlockedMutex(自旋锁)比1.25倍 - 1.75倍快Critical Section.

  • -1表示易失性.你不应该单独依赖volatile来进行线程化.使用原子,或将volatile与内存栅栏结合使用.否则,您的易失性访问最终可能会在Linux/gcc上重新排序. (2认同)