c/c++多线程编程中,为什么基本类型不用加锁?
1个回答
展开全部
首先 你描述的不对 严格来说是在对应的cpu体系下遵循了正确的内存对齐的方式的数据才有不需要加锁的可能
加锁主要是防止partial read/write以及cpu乱序带来的cpu操作可见性问题
举x86-64的例子来说 一个基本类型如果地址无cache splite(落在两个cacheline中) 都可以保证无partial read/write 请参考《intel 开发者手册》第三卷8.1.1.1章
另外一个功能就是杜绝cpu乱序引起的可见性问题了 仅局限于x86-64来说 如果你操控的这个基本类型对于storeload乱序不敏感 做到良好对齐就足够了 当然cpu乱序又是一个更深入的问题了 手机上说不清 一般来说 lock 都带有 mb-aquire的语意 unlock都带有mb-release的语意 因此加锁可以解决乱序问题
另外 题主怀疑多个缓存数据会不一致 这一点是不会发生的 这一点不是由操作系统保证的 而是每种cpu硬件都会遵守类似于mesi的缓存一致性协议 缓存的数据更改会在fsb上传递给各个其他cpu 这种复杂的一致性方式带来了性能问题 于是又引入了storebuffer和invalidate queue等机制来优化 从而导致cpu乱序的发生 又引入了各种memory barrior指令在必要时防止乱序的发生 在应用层这些被封装在各种锁里
上面所说局限于smp结构
加锁主要是防止partial read/write以及cpu乱序带来的cpu操作可见性问题
举x86-64的例子来说 一个基本类型如果地址无cache splite(落在两个cacheline中) 都可以保证无partial read/write 请参考《intel 开发者手册》第三卷8.1.1.1章
另外一个功能就是杜绝cpu乱序引起的可见性问题了 仅局限于x86-64来说 如果你操控的这个基本类型对于storeload乱序不敏感 做到良好对齐就足够了 当然cpu乱序又是一个更深入的问题了 手机上说不清 一般来说 lock 都带有 mb-aquire的语意 unlock都带有mb-release的语意 因此加锁可以解决乱序问题
另外 题主怀疑多个缓存数据会不一致 这一点是不会发生的 这一点不是由操作系统保证的 而是每种cpu硬件都会遵守类似于mesi的缓存一致性协议 缓存的数据更改会在fsb上传递给各个其他cpu 这种复杂的一致性方式带来了性能问题 于是又引入了storebuffer和invalidate queue等机制来优化 从而导致cpu乱序的发生 又引入了各种memory barrior指令在必要时防止乱序的发生 在应用层这些被封装在各种锁里
上面所说局限于smp结构
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询