谁能给我解释一下,为什么当一个线程两次尝试获取同一个自旋锁时会出现死锁?(假设自旋锁是非递归的)
常规自旋锁使用:
lock = false;
while(acquiring_lock(lock)) {} //sit in the loop and wait for lock to become available
....critical section....
release_lock(lock); 但是,我不明白为什么第二次调用acquiring_lock(lock)会导致死锁?
发布于 2013-04-08 12:18:16
这个问题似乎真的取决于所讨论的线程库,以及不同函数的规范。因此,让我们考虑几种可能性。
锁定机制可以是blocking或非阻塞的,也可以是re-entrant和不可重入的。
/**
* This function performs a busy wait, blocking until it acquires the lock
* This is not re-entrant.
**/
void blocking_acquire_lock(bool thingToLock);如果你尝试使用前面的函数,你的代码将会死锁。这是因为线程在获得锁之前不会继续执行。您不会在while循环的条件位置使用它,因为它不返回布尔值。其次,它不是可重入的,这意味着如果您尝试在获取锁之后重新获取它,即使使用相同的线程,它也将继续等待锁被释放。
/**
* This function performs a non-blocking busy wait, blocking for up to X milleseconds,
* until it acquires the lock. This is not re-entrant.
* returns true if lock acquired, false if lock not acquired
**/
bool non_blocking_acquire_lock(bool thingToLock, int timeoutInMilliseconds);这个版本在while循环中使用是有意义的。你可以尝试获取一个锁,但是如果在分配的时间内没有成功,你可以决定怎么做。也许,您会决定在其他方面工作一段时间,然后重新尝试获取锁。
因为它不是可重入的,所以它不允许同一线程两次获取它,除非首先释放它。因此,您的代码将死锁。
这是最后一个看起来会死锁在你的代码上的例子。
/**
* This function performs a non-blocking busy wait, blocking for up to X milleseconds,
* until it acquires the lock. This is re-entrant.
* returns true if lock acquired, false if lock not acquired
**/
bool non_blocking_reentrant_acquire_lock(bool thingToLock, int timeoutInMilliseconds);这个锁是可重入的,所以如果一个线程拥有这个锁,它就可以重新获取它。但是,如果您像下面这样在while循环中使用它,您会注意到一些有趣的事情。
my_lock = false;
while(acquiring_lock(my_lock, 1000)) { ; }
....critical section....
release_lock(lock); 由于如果在1秒内获取锁,锁将返回true,并且这是唯一的线程,因此它很可能会毫无问题地获取锁。它返回true。在这种情况下,它将停留在while循环中。while循环是空的,因此它会立即尝试重新获取锁。
由于它是可重入的,我预计它会继续成功。它将继续成功地重新获取锁,并且永远不会通过while循环。
我希望下面的代码带有额外的"!“去做你想做的事。
my_lock = false;
while( !acquiring_lock(my_lock, 1000)) { ; }
....critical section....
release_lock(lock); 这个版本实际上会停止获取锁的尝试,即一旦获取了锁,就会退出while循环。
https://stackoverflow.com/questions/15868204
复制相似问题