考虑到具体目的,Critical Sections
我Mutexes
认为您不能就成本提出问题,因为当您需要多个线程接触相同数据时,您没有太多选择。显然,如果你只需要增加/减少一个数字,你可以使用数字Interlocked*()
上的函数volatile
,你很高兴。但是对于更复杂的事情,您需要使用同步对象。
从这里开始阅读Windows^ 上可用的同步对象。所有功能都列在那里,很好地分组并正确解释。有些仅适用于 Windows 8。
至于你的问题,Critical Sections
比Mutexe
s 更便宜,因为它们被设计为在相同的过程中运行。阅读这个^和这个^或只是下面的报价。
临界区对象提供的同步类似于互斥对象提供的同步,但临界区只能由单个进程的线程使用。事件、互斥体和信号量对象也可以在单进程应用程序中使用,但临界区对象为互斥同步(特定于处理器的测试和设置指令)提供了更快、更有效的机制。与互斥对象一样,临界区对象一次只能由一个线程拥有,这对于保护共享资源不被同时访问非常有用。与互斥对象不同,没有办法判断临界区是否已被放弃。
我Critical Sections
用于相同的进程同步和Mutexes
跨进程同步。 只有当我真的需要知道同步对象是否被放弃时,我才会在同一进程中使用互斥锁。
因此,如果您需要一个同步对象,问题不在于成本是多少,而在于哪个更便宜:) 除了内存损坏之外别无选择。
PS:可能有像这里所选答案中提到的那样的替代方案^但我总是选择特定于核心平台的功能与跨平台性。它总是更快!因此,如果您使用 Windows,请使用 Windows 的工具 :)
更新
根据您的需要,您可以通过尝试在线程中做尽可能多的自包含工作并且仅在最后或不时地组合数据来减少对同步对象的需求。
愚蠢的例子:获取一个 URL 列表。你需要抓取它们并分析它们。
- 加入一堆线程并开始从输入列表中一个一个地挑选 URL。对于您的每一个过程,您在执行过程中都会集中结果。这是实时和酷的
- 或者,您可以将每个线程都放入具有输入 URL 切片的线程中。这消除了同步选择过程的需要。您将分析结果存储在线程中,最后只组合一次结果。或者说每 10 个 URL 一次。不是为他们每个人。这将大大减少同步操作。
因此,可以通过选择正确的工具并考虑如何降低锁定和解锁来降低成本。但成本无法消除:)
PS:我只考虑 URL :)
更新 2:
需要在项目中进行一些测量。结果非常令人惊讶:
- A
std::mutex
最贵。(跨平台的代价)
- Windows 本
Mutex
机比std
.
- A
Critical Section
比nativeMutex
快 2 倍。
- A
SlimReadWriteLock
是 的 +-10% Critical Section
。
- 我自制的
InterlockedMutex
(自旋锁)比Critical Section
.