Hazard pointers是一种无垃圾收集的无锁代码安全地回收内存的技术.

这个想法是在访问可以同时删除的对象之前,线程将其危险指针设置为指向该对象.要删除对象的线程将首先检查是否将任何危险指针设置为指向该对象.如果是这样,删除将被推迟,以便访问线程不会最终读取已删除的数据.

现在,假设我们的删除线程开始迭代危险指针列表,并且在第i个元素被抢占.现在另一个线程将我的危险指针设置为删除线程当前正在尝试删除的对象.之后,删除线程恢复,检查列表的其余部分,并删除对象,即使现在有一个位于指向对象的位置i的危险指针.

所以很清楚只是设置危险指针是不够的,因为删除线程可能已经检查了我们的危险指针,并决定我们的线程不想访问该对象.在设置危险指针后,如何确保我正在尝试访问的对象不会从我手中删除?

解决方法

权威答案

original paper by Maged M. Michael将这个重要的限制放在使用危险指针的算法上:

The methodology requires lock-free algorithms to guarantee that no
thread can access a dynamic node at a time when it is possibly removed
from the object,unless at least one of the thread’s associated hazard
pointers has been pointing to that node continuously,from a time when
the node was guaranteed to be reachable from the object’s roots. The
methodology prevents the freeing of any retired node continuously
pointed to by one or more hazard pointers of one or more threads from
a point prior to its removal.

删除线程意味着什么

正如Anton’s answer年所指出的那样,删除是一个两阶段的操作:首先你必须“取消发布”节点,从数据结构中删除它,使其不能再从公共接口访问.

在这一点上,迈克尔的术语可能会删除节点.并发线程访问它是不再安全的(除非他们已经持有一个危险指针).

因此,一旦节点可能被删除,删除线程可以安全地迭代危险指针列表.即使删除线程被抢占,并发线程也可能不再访问该节点.在验证没有将危险指针设置到节点之后,删除线程可以安全地进行到第二阶段的删除:实际的释放.

总之,删除线程的操作顺序是

D-1. Remove the node from the data structure.
D-2. Iterate the list of hazard pointers.
D-3. If no hazards were found,delete the node.

真正的算法稍微涉及,因为我们需要维护那些不能被回收的节点的列表,并确保最终被删除.这在这里已经被跳过了,因为它与解释问题提出的问题无关.

访问线程意味着什么

设置危险指示器不足以保证安全访问它.毕竟,在我们设置危险指针的时候,节点可能会被删除.

确保安全访问的唯一方法是,如果我们可以保证我们的危险指针从节点保证从对象的根目录到达的时间不断地指向该节点.

由于代码应该是无锁的,所以只有一种方法来实现这一点:我们乐观地将我们的危险指针设置到该节点,然后检查该节点是否被标记为可能被删除(即,它不再可达到从公共根).

因此,访问线程的操作顺序是

A-1. Obtain a pointer to the node by traversing the data structure.
A-2. Set the hazard pointer to point to the node.
A-3. Check that the node is still part of the data structure.
     That is,it has not been possibly removed in the meantime.
A-4. If the node is still valid,access it.

潜在的种族影响删除线程

在可能删除节点(D-1)之后,删除线程可能被抢占.因此,并发线程仍然可以乐观地将其危险指针设置为它(即使不允许访问它)(A-2).

因此,删除线程可能会检测到虚假危险,防止它立即删除节点,即使其他线程中没有一个将再次访问该节点.这将简单地延迟删除节点的方式与合法的危险相同.

重要的一点是节点最终将被删除.

影响访问线程的潜在竞赛

在验证节点未被潜在删除之前,访问线程可能被删除线程抢占(A-3).在这种情况下,不再允许访问该对象.

请注意,如果在A-2之后发生抢占,则访问线程访问节点甚至是安全的(因为存在指向节点的危险指针),但由于访问线程不可能区分这种情况下,它必须虚假地失败.

重要的一点是,如果一个节点没有被删除,那么它只会被访问.

多线程 – 具有危险指针的无锁存储器回收的更多相关文章

  1. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. iOS:核心图像和多线程应用程序

    我试图以最有效的方式运行一些核心图像过滤器.试图避免内存警告和崩溃,这是我在渲染大图像时得到的.我正在看Apple的核心图像编程指南.关于多线程,它说:“每个线程必须创建自己的CIFilter对象.否则,你的应用程序可能会出现意外行为.”这是什么意思?我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文).这在coreImage的上下文中是否有意义?

  3. ios – 多个NSPersistentStoreCoordinator实例可以连接到同一个底层SQLite持久性存储吗?

    我读过的关于在多个线程上使用CoreData的所有内容都讨论了使用共享单个NSPersistentStoreCoordinator的多个NSManagedobjectContext实例.这是理解的,我已经使它在一个应用程序中工作,该应用程序在主线程上使用CoreData来支持UI,并且具有可能需要一段时间才能运行的后台获取操作.问题是NSPersistentStoreCoordinator会对基础

  4. ios – XCode断点应该只挂起当前线程

    我需要调试多线程错误.因此,为了获得生成崩溃的条件,我需要在代码中的特定点停止一个线程,并等待另一个线程到达第二个断点.我现在遇到的问题是,如果一个线程遇到断点,则所有其他线程都被挂起.有没有办法只停止一个线程,让其他线程运行,直到它们到达第二个断点?)其他更有趣的选择:当你点击第一个断点时,你可以进入控制台并写入这应该在该断点处暂停当前上下文中的线程一小时.然后在Xcode中恢复执行.

  5. ios – 在后台线程中写入Realm后,主线程看不到更新的数据

    >清除数据库.>进行API调用以获取新数据.>将从API检索到的数据写入后台线程中的数据库中.>从主线程上的数据库中读取数据并渲染UI.在步骤4中,数据应该是最新数据,但我们没有看到任何数据.解决方法具有runloops的线程上的Realm实例,例如主线程,updatetothelatestversionofthedataintheRealmfile,因为通知被发布到其线程的runloop.在后台

  6. ios – Swift指针算术和解除引用;将一些类似C的地图代码转换为Swift

    我有一点似乎没有工作的Swift代码……解决方法您正在指定locationPointer指向新位置,但仍在下一行中使用ptr,并且ptr的值尚未更改.将您的最后一行更改为:或者你可以改变指向var的指针并推进它:

  7. ios – NSURLConnectionLoader线程中的奇怪崩溃

    我们开始看到我们的应用启动时发生的崩溃.我无法重现它,它只发生在少数用户身上.例外情况是:异常类型:EXC_BAD_ACCESS代码:KERN_INVALID_ADDRESS位于0x3250974659崩溃发生在名为com.apple.NSURLConnectionLoader的线程中在调用时–[NSBlockOperationmain]这是该线程的堆栈跟踪:非常感谢任何帮助,以了解可能导致这种崩

  8. ios – 合并子上下文时的NSObjectInaccessbileExceptions

    我尝试手动重现,但失败了.是否有其他可能发生这种情况的情况,是否有处理此类问题的提示?解决方法在创建子上下文时,您可以尝试使用以下行:

  9. ios – 从后台线程调用UIKit时发出警告

    你如何处理项目中的这个问题?

  10. ios – 如何防止Parse保存PFObject儿童?

    我正面临着Parse和iOS的一个非常普遍的问题.我有一个类POST,具有以下结构:>text(String)>图像(PFFile)>LikesUsers(StringofString)>LikesCount(Int)>从(发布到用户的指针)如果用户(已登录)喜欢帖子.我只是递增喜欢并将用户的Objectid添加到数组中例如:User-2喜欢User-1的帖子.问题在这里.我不能保存PostObj

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部