免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3879 | 回复: 6

[算法] c++和nginx的自选锁是真的自旋锁么 [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2016-06-28 16:52 |显示全部楼层
c++和nginx的自选锁是真的自旋锁么?
感觉如果你不关中断不关抢占,没办法实现自旋锁。
除非你有限制条件,例如一个CPU上只有一个线程访问该自选锁

论坛徽章:
0
发表于 2016-06-28 22:22 |显示全部楼层
你为什么有这种想法呢?

其实,自旋锁是用原子指令操作内存,内存是所有核共享的空间。
中断控制器每个核都有一个,所以关中断只能让本核不会产生中断。
如果要做核间锁,就必须用自旋锁(在不使用内核结构的前提下)。

自旋锁的机制很简单,就是对内存一个字进行原子交换,如果交换成功那么你就拥有了锁。别的核也能立刻“观察”到。
如果交换失败,说明别的线程已经拥有了锁,本线程就要不断的尝试,直到成功。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2016-06-28 22:46 |显示全部楼层
spinlock这种东西用原子操作实现要不了几行,具体的代码长这样:

  1. class spinlock
  2. {
  3. private:
  4.     typedef enum { Locked, Unlocked } LockState;
  5.     std::atomic<LockState> state_;

  6. public:
  7.     /// Constructor
  8.     spinlock() noexcept : state_(Unlocked) {}

  9.     /// Blocks until a lock can be obtained for the current execution agent.
  10.     void lock() noexcept
  11.     {
  12.         while (state_.exchange(Locked, std::memory_order_acquire) == Locked) {
  13.             /* busy-wait */
  14.         }
  15.     }

  16.     /// Releases the lock held by the execution agent.
  17.     void unlock() noexcept { state_.store(Unlocked, std::memory_order_release); }
  18. };
复制代码
唯一的问题就是它其实没什么大用,OS kernel用这东西可以理解,毕竟从OS kernel的角度看CPU并没有“空闲”的时候,但在用户态代码里用这东西绝大多数场合下只能烧CPU玩,你说一个用户进程霸占着CPU不还给OS到底要闹哪样。

论坛徽章:
0
发表于 2016-06-28 23:07 |显示全部楼层
回复 3# windoze

自旋用于短等待资源,多核下常用。

自旋内,不能什么都不做,x86应执行 pause 指令。
如果执行了多个pause仍然没有得到锁,可考虑sched_yield()

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2016-06-28 23:49 |显示全部楼层
回复 4# codechurch

然而你说的这个实现方式正好就是现在Linux下pthread_mutex的实现方式,也就是说你什么都不干直接用std::mutex就行。

论坛徽章:
0
发表于 2016-06-29 22:14 |显示全部楼层
回复 5# windoze

应该还有些不一样。
貌似pthread里用了futex来挂起、**。
它可能要自旋几次,如果还不能得到锁,会用futex悬挂起来,等待内核**。
这样避免了每回合的yield,长挂比每次yield,性能应提高不少。

论坛徽章:
0
发表于 2016-06-29 22:15 |显示全部楼层
codechurch 发表于 2016-06-29 22:14
回复 5# windoze

应该还有些不一样。


OMG, 【唤-醒】被马赛克了!!!

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP