<aside> 💡
</aside>
最初的lock 通过开关中断实现互斥:
1 void lock() {
2 DisableInterrupts();
3 }
4 void unlock() {
5 EnableInterrupts();
6 }
有三个缺点:
system problems第一次尝试:
1 typedef struct __lock_t { int flag; } lock_t;
2
3 void init(lock_t *mutex) {
4 // 0 -> lock is available, 1 -> held
5 mutex->flag = 0;
6 }
7
8 void lock(lock_t *mutex) {
9 while (mutex->flag == 1) // TEST the flag
10 ; // spin-wait (do nothing)
11 mutex->flag = 1; // now SET it!
12 }
13
14 void unlock(lock_t *mutex) {
15 mutex->flag = 0;
16 }
最简单的 spinlock 实现,但有个问题:mutex->flag = 1; mutex->flag = 0; 不是原子操作,被多个thread访问时,可能会发生 race condition 。
而且并未实现互斥功能。
TestAndSet 的自旋锁(图 28.3,第 8 页)TestAndSet(),使“测试+设置”变成不可分割的一步,避免竞态。typedef struct __lock_t {
int flag;
} lock_t;
void init(lock_t *lock) {
lock->flag = 0; // 0 表示锁空闲
}
void lock(lock_t *lock) {
while (TestAndSet(&lock->flag, 1) == 1)
; // 自旋等待直到获取锁
}
void unlock(lock_t *lock) {
lock->flag = 0;
}
TestAndSet() 实现示意: