前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++多线程-自旋锁

C++多线程-自旋锁

作者头像
cwl_java
发布2020-01-15 10:47:00
1.3K0
发布2020-01-15 10:47:00
举报
文章被收录于专栏:cwl_Javacwl_Java

自旋锁是SMP中经常使用到的一个锁。所谓的smp,就是对称多处理器的意思。在工业用的pcb板上面,特别是服务器上面,一个pcb板有多个cpu是很正常的事情。这些cpu相互之间是独立运行的,每一个cpu均有自己的调度队列。然而,这些cpu在内存空间上是共享的。举个例子说,假设有一个数据value = 10,那么这个数据可以被所有的cpu访问。这就是共享内存的本质意义。

我们可以看一段Linux 下的的自旋锁代码(kernel 2.6.23,asm-i386/spinlock.h),就可有清晰的认识了,

代码语言:javascript
复制
static inline void __raw_spin_lock(raw_spinlock_t *lock)  
{  
    asm volatile("\n1:\t"  
             LOCK_PREFIX " ; decb %0\n\t"  
             "jns 3f\n"  
             "2:\t"  
             "rep;nop\n\t"  
             "cmpb $0,%0\n\t"  
             "jle 2b\n\t"  
             "jmp 1b\n"  
             "3:\n\t"  
             : "+m" (lock->slock) : : "memory");  
}  

上面这段代码是怎么做到自旋锁的呢?我们可以一句一句看看,

line 4: 对lock->slock自减,这个操作是互斥的,LOCK_PREFIX保证了此刻只能有一个CPU访问内存 line 5: 判断lock->slock是否为非负数,如果是跳转到3,即获得自旋锁 line 6: 位置符 line 7: lock->slock此时为负数,说明已经被其他cpu抢占了,cpu休息一会,相当于pause指令 line 8: 继续将lock->slock和0比较, line 9: 判断lock->slock是否小于等于0,如果判断为真,跳转到2,继续休息 line 10: 此时lock->slock已经大于0,可以继续尝试抢占了,跳转到1 line 11: 位置符

上面的操作,除了第4句是cpu互斥操作,其他都不是。所以,我们发现,在cpu之间寻求互斥访问的时候,在某一时刻只有一个内存访问权限。所以,如果其他的cpu之间没有获得访问权限,就会不断地查看当前是否可以再次申请自旋锁了。这个过程中间不会停歇,除非获得访问的权限为止。

总结: 1)在smp上自旋锁是多cpu互斥访问的基础 2)因为自旋锁是自旋等待的,所以处于临界区的代码应尽可能短 3)上面的LOCK_PREFIX,在x86下面其实就是“lock”,gcc下可以编过,朋友们可以自己试试

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档