在Windows上互斥、关键部分等的成本
Cost of mutex,critical section etc on Windows
我在某个地方读到互斥的开销并不大,因为上下文切换只在争用的情况下发生。
Linux中也称为Futex。
同样的东西在Windows中适用吗?Critical Section是Linux中更适合互斥的映射吗。
根据我所收集的信息,与Mutex相比,Critical Sections提供了更好的最佳性能,这在所有情况下都是真的吗?
在Windows中,是否存在互斥量比关键部分快的情况。
假设只有一个进程线程正在访问互斥对象(只是为了消除关键部分的其他好处)
添加信息:操作系统windows服务器,
语言C++
考虑到Critical Sections
和Mutexes
的特定用途,我认为您不能问关于成本的问题,因为当您需要多个线程处理相同的数据时,您没有太多选择。显然,如果您只需要增加/减少一个数字,您可以在volatile
数字上使用Interlocked*()
函数,这样就可以了。但对于任何更复杂的情况,都需要使用同步对象。
从这里开始阅读Windows^上可用的同步对象。所有功能都列在那里,很好地分组并进行了适当的解释有些只是Windows 8
关于您的问题,Critical Sections
比Mutexe
便宜,因为它们设计用于在相同的过程中操作阅读这个^和这个^,或者只阅读下面的引文。
关键部分对象提供与互斥对象类似的同步,只是关键部分只能由单个进程的线程使用。事件、互斥对象和信号量对象也可以在单个进程应用程序中使用,但关键部分对象为互斥同步(特定于处理器的测试和设置指令)提供了一种稍微更快、更高效的机制。与互斥对象一样,关键部分对象一次只能由一个线程拥有,这对于保护共享资源免受同时访问非常有用。与互斥对象不同,无法判断关键部分是否已被放弃。
我使用Critical Sections
进行同进程同步,使用Mutexes
进行跨进程同步
只有当我真的需要知道同步对象是否被放弃时,我才会在同一过程中使用Mutex
所以,如果你需要一个同步对象,问题不是成本是多少,而是哪个更便宜:)除了内存损坏,别无选择
PS:可能有其他选择,比如这里选择的答案中提到的,但我总是选择核心平台特定功能与跨平台。它总是更快因此,如果您使用Windows,请使用Windows的工具:)
更新
根据您的需要,您可以通过尝试在线程中尽可能多地执行自包含的工作来减少同步对象的需要,并且只在最后或不时地组合数据。
愚蠢的例子:获取URL列表。你需要搜集并分析它们
- 加入一堆线程,开始从输入列表中一个接一个地选择URL。对于你的每一个过程,你都会在进行过程中集中结果。这是实时的,很酷
- 或者,您可以在每个线程中放入一个输入URL片段。这样就不需要同步选择过程。您将分析结果存储在线程中,最后只需组合一次结果。或者说,每10个URL就有一次。不是为他们每个人。这将大大减少同步操作
因此,可以通过选择正确的工具并思考如何降低锁定和解锁来降低成本。但成本无法去除:)
PS:我只在URL中思考:)
更新2:
有必要在一个项目中做一些测量。结果非常令人惊讶:
-
std::mutex
是最昂贵的(跨平台价格) -
Windows本机
Mutex
比std
快2倍 -
Critical Section
比原生Mutex
快2倍 -
SlimReadWriteLock
是Critical Section
的+-10% - 我自制的
InterlockedMutex
(spinlock)比Critical Section
快1.25倍-1.75倍
在windows 8上使用std::mutex,通过使用我自己定制的旋转锁,我通常可以获得3-4x的改进(在非竞争情况下)
基于互斥的
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上使用下划线是什么,因为它生成了很多代码。
- 如何覆盖Windows键盘快捷键
- 如何在我的 Windows 应用程序中捕获按下和释放的 CTRL 键?
- 如何监控Android和iOS上的所有击键操作,如Windows键盘记录器
- C :模拟键,如果在Windows上按下,请将其维护
- 电子内部或外部方法创建自己的右键单击上下文菜单 - Windows
- Windows API-用多个键组合注册热键
- Windows虚拟键代码
- 当您按"Enter"键时,Windows超级终端下发送哪些字符
- 如何在 Windows 资源管理器中捕获用户的左键单击?
- 使用CNG存储功能导入Windows密钥存储中的持久键
- 将菜单项添加到Windows Explorer右键单击Java中的上下文菜单
- Windows 资源管理器右键单击文件和文件夹的上下文菜单
- "Windows"按钮的C++键扫描码是什么?
- 如何在 Windows Mobile 6.5 (c++) 中判断何时按下某个键
- 奇怪的Windows消息序列WM_KEYDOWN/WM_KEYUP,同时按VK_MENU(Alt键)
- 如何显示 Windows 资源管理器上下文(右键单击)菜单
- 如何拦截 Windows 命令提示符的击键
- Windows:如何在低级键盘挂钩中查询修饰键的状态
- 强制触发键关闭事件 (Windows)
- 从我的Windows应用程序管理蓝牙遥控快门键