2016-07-22 47 views
0

我想了解如何在锁实现中使用读取和添加(原子操作)。取和添加说明错误?

我在维基百科遇到这篇文章,我发现它在至少一个其他地方重复。实现没有意义,并期待我有一个或更多的错误。当然,我可能会错过一个微妙的点,而不是真正理解正在描述的内容。

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

永远是正确的。

在这个插图中有错误还是我错过了一些东西?

如果在这个实现中有一个错误,它会修复它吗?

感谢名单

朱利安

回答

0

荡它,现在我明白了。我发现它指的是算法的一般描述,然后我更仔细地查看它。

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

当它旋转时,它会等待另一个线程递增并最终成为myturn的数量。

对不起,浪费你的时间。

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