![]() |
打盹的桔子 · 【C#】List<T>类型强制转换_c# ...· 11 月前 · |
![]() |
坏坏的骆驼 · stdlib.h:没有此类文件或目录-腾讯云 ...· 1 年前 · |
![]() |
沉着的西红柿 · java世界中几种html解析的工具_jav ...· 1 年前 · |
![]() |
鼻子大的烈酒 · sqlite怎样给字段设置默认值?_百度知道· 1 年前 · |
在这个网站上,我经常在其他论坛上读到这样的话:“互斥很重,最好用别的东西”。但是我真的不能解释为什么它很重?此外,如果我们在讨论C++20之前的标准C++11,我们基本上只有std::mutex,与锁或condition_variable一起使用,以使某些东西是线程安全的,我期望来自std的东西是相当有效的,特别是如果它是(在C++20之前)唯一能完成一些任务的工具,在这种情况下是线程安全的。那么为什么互斥锁特别是std::互斥锁很重呢?作为C++开发人员,我们应该使用什么来代替呢?来自boost的东西?
发布于 2021-03-06 22:39:00
Mutexes被认为是“繁重的”,因为它们通常被认为会导致syscall,即到内核的往返。由于特权和非特权代码之间的上下文切换,对内核的访问占用了1,000+ CPU周期的顺序。
如今,在许多OSes中,互斥锁都经过了优化,直到发生争用时才进入内核。例如,在Linux中,它是在Windows - SRW锁中使用futex (“快速用户空间互斥锁”)实现的。然而,一旦出现争用,就会有一次内核之旅。一旦线程需要等待,它将被操作系统“休眠”,并且在锁被释放的时刻和线程被调度再次执行的时间之间将有一个显著的延迟。
如果您需要同步,有时在一个简单的
atomic
上执行循环就足够了。如果争用很少且很短,那么您可以使用“自旋锁”来实现更好的性能,即循环直到满足特定条件。即使你循环10000次,它也比一次syscall更快。
然而,在实践中,互斥锁将在性能和便利性之间提供足够的平衡。所以我不会担心它,除非你在计算纳秒(就像在HFT或实时应用程序中)。
发布于 2021-03-06 22:22:53
std::mutex
被设计成一个围绕操作系统的本机互斥锁设施的轻量级便携包装器。如果您的目标是调用这些工具,那么与直接调用操作系统原生应用程序接口相比,
mutex
引入的开销可以忽略不计。
但是,根据您的用例,使用OS工具可能不是最佳解决方案。例如,为了保护数据不被并发访问,您还可以使用诸如
std::atomic
之类的低级原语编写自己的锁。然而,这将是一种不同的锁定算法。特别是,如果不能立即获得互斥锁,
std::mutex
将使等待线程休眠,这是在不与操作系统交谈的情况下无法做到的事情。但在某些情况下,这样一个更简单的锁定算法就足以完成工作。这里的一个常见示例是锁争用预计仅在极少数情况下发生。
话虽如此,这样的想法会让你深入到专家级并发编程中。除非您有需要担心微优化的特定问题,如滚动您自己的锁定,否则
std::mutex
是可行的方法,它的开销很好地限制了它所做的事情。
发布于 2021-03-06 22:44:22
所有类型的同步都是“重”的,并且基于锁的同步比原子的重。
https://github.com/markwaterman/MutexShootout
这个人在不同的互斥实现之间做了一个比较。原始的windows SWR锁是最快的选择,但他们比较的最新的std mutex是MSVC 2017锁。
我相信
std::shared_mutex
是一把隐藏在引擎盖下的windows SRW锁。
你需要每一个最小的性能百分比吗?然后,您应该分析并交换互斥锁。如果不是,
std::mutex
距离最佳选项的百分比不到10s,并且可能会继续迭代和支持。
原子整数操作通常比互斥锁更便宜,但规则更复杂。此外,原子操作会导致代码中的非本地减速,因为它会导致缓存线被清除,以避免其他人具有错误的值。
根据我的经验,在您遇到极端情况之前,您可以通过更改算法来获得远远超过10%的性能更改。当你真的,真的需要性能时,你可能会尽可能多地去掉互斥锁;即使是最快的互斥锁也不足以满足真正高性能的情况。
优化是可替换的;当您发现瓶颈时,您可以花费开发精力使代码变得更快。不要编写过早悲观的代码;但是使用std互斥锁造成的10%的命中率通常不足以解决这个问题。
https://stackoverflow.com/questions/66506475
复制相似问题
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
![]() |
鼻子大的烈酒 · sqlite怎样给字段设置默认值?_百度知道 1 年前 |