多线程 – 使用细粒度方法线程安全删除链表节点
为什么删除链表中的节点的以下代码段不是线程安全的?
编辑:注意每个节点都有自己的锁 // ... lock acquisition here // ... assumption found to be valid here prev->next = p->next; p->next = NULL; p->deleted = 1; 解决方法
它是线程安全的,假设你的锁的范围(意味着它锁定的内容,与C中使用的官方术语“范围”无关)足够大.
如果它只锁定当前节点p,那么你就不能依赖其他线程来进入并使用prev(或者头部或尾部)并因此削弱你. 如果它锁定整个结构,那么是的,它是线程安全的. 我们无法从给出的代码中告诉您锁的范围,但我会提到另一个(无关的)事情. 您可能应该释放p或将其添加到空闲列表以供重复使用.只需将其下一个指针设置为null并将其已删除的标志设置为1,就无法在需要重用它时找到它.这将导致内存泄漏.可能是这样做的代码没有显示,但我想我会提到它,以防万一. 根据您的编辑,您声明您正在使用细粒度方法(每个节点一个锁): 如果您锁定了正在使用或更改的所有三个“节点”,并且将它们锁定在一致的方向上,它仍然是线程安全的. 我把“节点”放在引号中,因为它也适用于头部和尾部指针.例如,如果要删除十节点列表中的第一个节点,则需要按顺序锁定头变量以及第一个和第二个节点.要删除单节点列表中的最后一个节点,需要同时锁定头部和尾部变量以及节点. 锁定所有三个“节点”将防止线程相互产生不利影响. 将它们锁定在一致的方向(例如从头部到尾部)将防止死锁. 但是在尝试改变任何东西之前你必须锁定所有三个. 这甚至会阻止它进行并发插入操作,只要插入锁定插入点两侧的两个“节点”,当然,它们将它们锁定在同一方向上. 不确定在列表上迭代的程度如何.你可能可以使用一个系统,你最初锁定head变量和第一个节点,然后释放头. 然后,当您完成该节点后,在释放当前节点之前锁定下一个节点.这样,您应该能够在不受插入或删除影响的情况下遍历列表,这只能在您当前未使用的区域中进行. 但是,最重要的是,即使使用细粒度锁定范围,您也可以确保线程安全. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |