获取和添加描述错误



我正在努力了解如何在锁实现中使用fetch和add(原子操作)。

我在维基百科上看到了这篇文章,我发现它至少在另一个地方有重复。这个实现没有意义,在我看来有一个或更多的错误。当然,我可能错过了一个微妙的点,也没有真正理解所描述的内容。

发件人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=1lock.turn=0。

比方说,在锁被释放之前,还会发生5次对锁的访问。

lock.ticketnumber=6lock.turn=0

第一个线程释放锁。

lock.ticketnumber=6lock.turn=1

下一个线程进入,状态为

lock.ticketnumber=7lock.turn=1

返回值:myturn=6(faa之前的lock.ticketnumber)。

在这种情况下:

而lock.turn≠myturn

不可能是真的。

这幅插图中有错误吗?还是我遗漏了什么?

如果这个实现中有一个bug,该怎么修复呢?

Thanx

Julian

该死,我现在看到了。我发现它指的是算法的一般描述,然后我更仔细地看了看。

当一个线程调用Lock时,它会旋转等待返回的值,出于某种原因,我认为它一直在调用那个函数。

当它旋转时,它会等待,直到另一个线程增加匝数,并最终成为myturn的数目。

很抱歉浪费了你的时间。

https://en.wikipedia.org/wiki/Ticket_lock

相关内容

  • 没有找到相关文章

最新更新