网站工具查询,怎样做自己的销售网站,微信定制版app,广东计算机网页制作原子操作和自旋锁的区别 相同点都是保护共享资源。 不同点在于#xff1a; 原子操作简单易用#xff0c;但只能做计数操作#xff0c;保护的东西太少。 自旋锁主要用于多核处理器。短时期的轻量级加锁#xff0c;加锁失败时原地打转、忙等待。避免了上下文调度和系统开销较…
原子操作和自旋锁的区别 相同点都是保护共享资源。 不同点在于 原子操作简单易用但只能做计数操作保护的东西太少。 自旋锁主要用于多核处理器。短时期的轻量级加锁加锁失败时原地打转、忙等待。避免了上下文调度和系统开销较小。 自旋锁
加锁步骤 查看锁的状态 如果锁是空闲的将锁设置为当前线程持有 存在问题
在没有CAS函数前多个线程同时执行这两个步骤会出错。
解决方案
CAS函数把这两个步骤合并为一条硬件级指令。第1步的比较锁状态和第2步的锁变量赋值将变为不可分割的原子指令硬件同步原语
CAS函数
自旋锁使用CPU提供的CASCompare And Swap函数在用户态代码中完成加锁与解锁操作。
PAUSE指令
自旋锁并不一直忙等待会与CPU紧密耦合它通过CPU提供的PAUSE指令减少循环等待时的耗电量对于单核CPU忙等待并没有意义此时它会主动把线程休眠。
自旋锁原理 设自旋锁为变量lock整数0表示锁是空闲状态整数pid表示线程ID。 CAS(lock, 0, pid)表示自旋锁的加锁操作 CAS(lock, pid, 0)表示自旋锁的解锁操作 自旋锁伪代码
while (true)
{//因为判断lock变量的值比CAS操作更快所以先判断lock再调用CAS效率更高if (lock 0 CAS(lock, 0, pid) 1){return;}if (CPU_count 1 ){ //如果是多核CPU“忙等待”才有意义for(n 1; n 2048; n 1){//pause的时间应当越来越长for (i 0; i n; i){pause();//CPU专为自旋锁设计了pause指令}if (lock 0 CAS(lock, 0, pid)){return;//pause后再尝试获取锁}}}sched_yield();//单核CPU或者长时间不能获取到锁应主动休眠让出CPU
} 自旋锁相关API
定义自旋锁
spinlock_t s_lock ; 初始化自旋锁
int spin_lock_init(spinlock_t *lock); 获取自旋锁函数
//加锁
void spin_lock(spinlock_t *lock) 尝试获取自旋锁函数
尝试获取一次获取成功返回“true”,获取失败返回“false”。程序继续往下执行 与上面的区别就是非阻塞
int spin_trylock(spinlock_t *lock) 释放自旋锁
void spin_unlock(spinlock_t *lock);