多线程 – 一般来说,Re-entrant锁和概念是什么?

我总是困惑。会有人解释什么Reentrant意味着在不同的情况下?为什么要使用可重入和不可重入?

说pthread(posix)锁定原语,他们是否重入?使用它们时应避免什么陷阱?

互斥体是否重入?

进入锁定

可重入锁是其中进程可以多次声明锁定而不阻塞自身的锁。它在那些不容易跟踪你是否已经抓住锁的情况下非常有用。如果锁是不可重入的,你可以抓住锁,然后阻止当你再次抓住它,有效地锁死你自己的过程。

重入通常是代码的属性,它没有中央可变状态,如果代码在执行时被调用,它可能被破坏。这样的调用可以由另一个线程进行,或者它可以由源于代码本身内的执行路径递归地进行。

如果代码依赖于可以在其执行的中间被更新的共享状态,则它不是重入的,至少不是如果该更新可能中断它。

用于重入锁定的用例

可重入锁的应用程序的一个(有点通用和设计)示例可能是:

>你有一些计算涉及到一个遍历一个图的算法(可能有一个循环)。由于循环或由于到同一节点的多个路径,遍历可以访问同一节点多于一次。
>数据结构受到并发访问的限制,并且可能由于某种原因(可能由另一个线程)更新。您需要能够锁定单个节点以处理由于竞争条件导致的潜在数据损坏。由于某种原因(可能是性能),您不想全局锁定整个数据结构。
>您的计算不能保留您访问过的节点的完整信息,或者您使用的数据结构不允许“我已经在这里”的问题要快速回答。这种情况的一个例子是Dijkstra算法的简单实现,优先级队列实现为二进制堆或使用简单链表作为队列的宽度优先搜索。在这些情况下,扫描队列中的现有插入是O(N),您可能不想在每次迭代时都执行此操作。

在这种情况下,跟踪你已经获得的锁是昂贵的。假设您希望在节点级别执行锁定,重入锁定机制可以减轻您是否曾经访问过某个节点的需要。你可以只是盲目地锁定节点,也许解锁它,当你把它从队列中。

重入互斥体

一个简单的互斥不是重入的,因为在给定时间只有一个线程可以在临界区。如果你抓住互斥,然后尝试再次抓住它,一个简单的互斥没有足够的信息,以告诉谁是先前持有它。为了递归地做到这一点,你需要一个机制,每个线程都有一个令牌,所以你可以告诉谁抓住互斥体。这使得互斥机制有点贵,所以你可能不想在所有情况下都这样做。

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

http://stackoverflow.com/questions/1312259/what-is-the-re-entrant-lock-and-concept-in-general

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:多线程 – 一般来说,Re-entrant锁和概念是什么?