首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么当线程两次尝试获取相同的自旋锁时会出现死锁?

为什么当线程两次尝试获取相同的自旋锁时会出现死锁?
EN

Stack Overflow用户
提问于 2013-04-08 05:44:54
回答 1查看 2K关注 0票数 1

谁能给我解释一下,为什么当一个线程两次尝试获取同一个自旋锁时会出现死锁?(假设自旋锁是非递归的)

常规自旋锁使用:

代码语言:javascript
运行
复制
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)会导致死锁?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-08 12:18:16

这个问题似乎真的取决于所讨论的线程库,以及不同函数的规范。因此,让我们考虑几种可能性。

锁定机制可以是blocking或非阻塞的,也可以是re-entrant和不可重入的。

代码语言:javascript
运行
复制
/** 
* This function performs a busy wait, blocking until it acquires the lock
* This is not re-entrant.
**/
void blocking_acquire_lock(bool thingToLock);

如果你尝试使用前面的函数,你的代码将会死锁。这是因为线程在获得锁之前不会继续执行。您不会在while循环的条件位置使用它,因为它不返回布尔值。其次,它不是可重入的,这意味着如果您尝试在获取锁之后重新获取它,即使使用相同的线程,它也将继续等待锁被释放。

代码语言:javascript
运行
复制
/** 
* 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循环中使用是有意义的。你可以尝试获取一个锁,但是如果在分配的时间内没有成功,你可以决定怎么做。也许,您会决定在其他方面工作一段时间,然后重新尝试获取锁。

因为它不是可重入的,所以它不允许同一线程两次获取它,除非首先释放它。因此,您的代码将死锁。

这是最后一个看起来会死锁在你的代码上的例子。

代码语言:javascript
运行
复制
/** 
* 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循环中使用它,您会注意到一些有趣的事情。

代码语言:javascript
运行
复制
my_lock = false; 
while(acquiring_lock(my_lock, 1000)) { ; }
    ....critical section....
release_lock(lock);  

由于如果在1秒内获取锁,锁将返回true,并且这是唯一的线程,因此它很可能会毫无问题地获取锁。它返回true。在这种情况下,它将停留在while循环中。while循环是空的,因此它会立即尝试重新获取锁。

由于它是可重入的,我预计它会继续成功。它将继续成功地重新获取锁,并且永远不会通过while循环。

我希望下面的代码带有额外的"!“去做你想做的事。

代码语言:javascript
运行
复制
my_lock = false; 
while( !acquiring_lock(my_lock, 1000)) { ; }
    ....critical section....
release_lock(lock);  

这个版本实际上会停止获取锁的尝试,即一旦获取了锁,就会退出while循环。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15868204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档