0

下面是OSTEP 书中关于使用测试和设置指令实现锁的代码。我的问题是,在这样的实现中,没有持有锁的线程不能调用解锁函数并拿走锁吗?

typedef struct __lock_t {
 int flag;
 } lock_t;

 void init(lock_t *lock) {
 // 0 indicates that lock is available, 1 that it is held
 lock->flag = 0;
 }

 void lock(lock_t *lock) {
 while (TestAndSet(&lock->flag, 1) == 1)
 ; // spin-wait (do nothing)
 }

 void unlock(lock_t *lock) {
 lock->flag = 0;
 }
4

2 回答 2

0

我的问题是,在这样的实现中,没有持有锁的线程不能调用解锁函数并拿走锁吗?

(例如)一个线程获取锁,通知另一个线程它可以继续(或者可能产生一个新线程),然后另一个线程释放锁,这没有任何问题。

如果单个线程获得了一个锁,然后两次释放它,那是非常错误的。

要检测错误(同时仍支持所有合法场景),您需要检测“unlock()未持有锁时调用”。您可以通过TestAndClear()unlock().

如果您想强制“只有获得锁的线程可以释放锁”,那么您必须知道哪个线程获得了锁,因此您必须在获得锁时将线程 ID 存储在锁中(例如,可能通过使用原子“比较,如果相等则交换”)。

于 2022-02-12T17:58:55.027 回答
0

假设这是一个编码错误,因此不应发生这种情况。

于 2022-02-12T16:50:35.710 回答