我想了解如何在锁实现中使用读取和添加(原子操作)。取和添加说明错误?
我在维基百科遇到这篇文章,我发现它在至少一个其他地方重复。实现没有意义,并期待我有一个或更多的错误。当然,我可能会错过一个微妙的点,而不是真正理解正在描述的内容。
从https://en.wikipedia.org/wiki/Fetch-and-add
<<atomic>>
function FetchAndAdd(address location, int inc) {
int value := *location
*location := value + inc
return value
}
record locktype {
int ticketnumber
int turn
}
procedure LockInit(locktype* lock) {
lock.ticketnumber := 0
lock.turn := 0
}
procedure Lock(locktype* lock) {
int myturn := FetchAndIncrement(&lock.ticketnumber) //must be atomic, since many threads might ask for a lock at the same time
while lock.turn ≠ myturn
skip // spin until lock is acquired
}
procedure UnLock(locktype* lock) {
FetchAndIncrement(&lock.turn) //this need not be atomic, since only the possessor of the lock will execute this
}
根据这篇文章,他们首先做LockInit。 FetchAndIncrement调用FetchAndAdd并将inc设置为1.
如果这不包含错误,我不明白它如何工作。
第一个线程访问它会得到它:
lock.ticketnumber = 1 lock.turn = 0
比方说,被释放前5次访问,以锁定发生。
lock.ticketnumber = 6 lock.turn = 0
第一线程释放该锁。
lock.ticketnumber = 6 lock.turn = 1
接着螺纹进来和状态将是
lock.ticketnumber = 7 lock.turn = 1
,且返回值:myturn = 6(faa之前的lock.ticketnumber)。
在这种情况下:
而lock.turn≠myturn
永远是正确的。
在这个插图中有错误还是我错过了一些东西?
如果在这个实现中有一个错误,它会修复它吗?
感谢名单
朱利安