<aside> 💡

threads-locks.pdf

</aside>

最初的lock 通过开关中断实现互斥:

1 void lock() {
2 DisableInterrupts();
3 }
4 void unlock() {
5 EnableInterrupts();
6 }

有三个缺点:

第一次尝试:

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() 实现示意: