首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是重新进入的锁和概念在一般情况下?

什么是重新进入的锁和概念在一般情况下?
EN

Stack Overflow用户
提问于 2009-08-21 14:22:11
回答 4查看 64.9K关注 0票数 129

我总是很困惑。有人能解释一下重入在不同背景下的含义吗?你为什么要使用“重入者”与“不可重入者”?

比如说,p线程(posix)锁定原语,它们是否是可重入的?使用它们时应该避免哪些陷阱?

互斥是可重入的吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-08-21 14:25:54

可重入锁

可重入锁是一个进程可以多次声明锁而不阻塞自身的锁。在不容易跟踪您是否已经抓起锁的情况下,它是有用的。如果一个锁是不可重入的,你可以抓住这个锁,然后当你再次抓住它的时候阻塞它,有效地锁定你自己的进程。

一般情况下,可重入性是代码的一个属性,在代码执行过程中,如果代码被调用,则它没有中央可变状态。这样的调用可以由另一个线程执行,也可以由代码本身内部的执行路径递归执行。

如果代码依赖于可以在其执行过程中更新的共享状态,那么它就不是可重入者,至少如果该更新可能破坏它的话。

--可重入锁用例

可重入锁的应用程序示例(有些是通用的和人为的)可能是:

  • 您有一些涉及遍历图(可能包含循环)的算法的计算。由于周期或同一节点的多条路径,遍历可以多次访问同一节点。
  • 数据结构受并发访问的限制,可能由于某些原因而更新,可能是由另一个线程更新的。您需要能够锁定单个节点,以处理由于竞争条件导致的潜在数据损坏。由于某些原因(可能是性能),您不希望全局锁定整个数据结构。
  • 您的计算无法保留您访问过的节点的完整信息,或者您使用的数据结构不允许快速回答“我以前来过这里”的问题。

这种情况的一个例子是Dijkstra算法的一个简单实现,其优先级队列实现为二进制堆,或者使用简单的链表作为队列进行宽度优先搜索。在这些情况下,扫描队列以查找现有的插入是O(N),您可能不希望在每次迭代中都这样做。

在这种情况下,跟踪您已经获得的锁是很昂贵的。假设您想要在节点级别执行锁定,则重新进入锁定机制可以减轻判断您以前是否访问过某个节点的需要。您可以盲目地锁定节点,也许在弹出队列后将其解锁。

可重入互斥体

一个简单的互斥不能重新进入,因为在给定的时间,只有一个线程可以在关键部分。如果您抓取互斥对象,然后再次尝试抓取它,那么一个简单的互斥体就没有足够的信息来告诉谁之前持有它。要递归地这样做,您需要一个机制,其中每个线程都有一个令牌,这样您就可以知道是谁抓取了互斥对象。这使得互斥机制更昂贵,所以您可能不想在所有情况下都这样做。

IIRC POSIX线程API确实提供了可重入和非重入互斥的选项。

票数 201
EN

Stack Overflow用户

发布于 2009-08-21 14:33:54

可重入锁允许您编写一个方法M,它将一个锁放在资源A上,然后递归地调用M,或者从已经持有A锁的代码中调用M

使用非重入锁,您需要两个版本的M,一个锁的和一个没有锁的,并需要额外的逻辑来调用正确的一个。

票数 26
EN

Stack Overflow用户

发布于 2014-03-05 12:35:03

这个教程很好地描述了重入锁。

本教程中的示例比遍历图的答案少得多。在非常简单的情况下,重入锁很有用。

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

https://stackoverflow.com/questions/1312259

复制
相关文章

相似问题

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