不关抢占的自旋锁
假设A线程获得锁后,此时存在B线程并且B线程优先级高,A线程被抢占挂起,B线程尝试访问相同的临界资源,B线程就可能会陷入活锁状态,不断尝试获得锁、失败、尝试获得锁、失败…
不关中断的自旋锁
假设CPU是单核的,进程获得了锁并访问临界资源,此时被中断,接着执行中断例程,当中断例程也访问相同的临界资源,此时进程就会陷入活锁状态
无优先级自旋锁
如果CPU处理器很多,就可能出现某些线程一直获取不到锁的情况
FIFO的自旋锁
-
排队自旋锁
struct spin_lock { uint32_t next_; };
内部维护一个整型,H表示next_高2个字节,L表示低两个字节。每次lock时,存在以下伪代码:
/*********原子执行**********/ uint32_t tmp = spin_lock->next_; spin_lock->next_ += 0x00010000; /*************************/ while(true) if(H(tmp) == L(spin_lock->next_)) success; break; else failed;
free_lock时:
/*********原子执行**********/ spin_lock->next_ += 0x00000001; /*************************/
-
Queued Spinlock(WIndows内核)
当线程尝试获得被其他线程占有的锁时,此线程会将一个标识加入到一个队列中,并等待这个标识。当线程释放锁时,会从队列中取一个标识设置为ready状态。因此,相比上文提到的排队自旋锁,Queued Spinlock优势是每个自旋等待的线程不会自旋在同一个变量上,减小处理器之间的同步。