Mr.CCCCCCCC 2021-12-20 16:39 采纳率: 100%
浏览 20
已结题

关于<<C++并发编程实战>>第七章 无锁并发数据结构设计中的一点疑惑


void try_reclaim(node* old_head)
{
if(threads_in_pop==1) // 1
{
node* nodes_to_delete=to_be_deleted.exchange(nullptr); // 2 声明“可删除”列表
if(!--threads_in_pop) // 3 是否只有一个线程调用pop()?
{
delete_nodes(nodes_to_delete); // 4
}
else if(nodes_to_delete) // 5
{
chain_pending_nodes(nodes_to_delete); // 6
}
delete old_head; // 7
}
else
{
chain_pending_node(old_head); // 8
--threads_in_pop;
}
}
```c++


//--------------------------------------------------------

在注释3处,假设此时的threads_in_pop为0了,但他也不能保证他的下一刻不为0啊,他为什么能删除这个待删除链表啊?
而且注释1和注释3不是冲突了嘛
  • 写回答

2条回答 默认 最新

  • 关注

    在注释3处,假设此时的threads_in_pop为0了,但他也不能保证他的下一刻不为0啊,他为什么能删除这个待删除链表啊?

    -

    你大概没明白这个回收逻辑,nodes_to_delete 是属于线程的私有变量,threads_in_pop 为 0,意味着 nodes_to_delete 和任何其它线程都无关了,threads_in_pop 哪怕再增加100,也只与 to_be_deleted 有关,自然可安全删除。

    -

    但是如果 threads_in_pop 不为 0,意味着 to_be_deleted 可能回收了其它线程传出的 old_head,而这个 old_head 可能同时被很多个线程引用,并且进行解引用操作,此时 nodes_to_delete 与 to_be_deleted 交换,其节点中,就必然有被其它多个线程引用的资源,一旦删除,会发生各种意想不到的问题。

    -

    而且注释1和注释3不是冲突了嘛

    -

    注释1和注释3的意义完全不同,1 是说 pop 已经将 head 后移一位了,其 oldhead 只有这么一个引用,可安全删除。而 3 是说 nodes_to_delete 已经和所有其它线程切割关系,没有任何线程引用其节点,可以安全的将其删除了。

    本回答被专家选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月2日
  • 专家已采纳回答 9月24日
  • 创建了问题 12月20日

悬赏问题

  • ¥20 要做柴油机燃烧室优化 需要保持压缩比不变 请问怎么用AVL fire ESE软件里面的 compensation volume 来使用补偿体积来保持压缩比不变
  • ¥15 算能的sail库的运用
  • ¥15 'Content-Type': 'application/x-www-form-urlencoded' 请教 这种post请求参数,该如何填写??重点是下面那个冒号啊
  • ¥15 找代写python里的jango设计在线书店
  • ¥15 请教如何关于Msg文件解析
  • ¥200 sqlite3数据库设置用户名和密码
  • ¥15 AutoDL无法使用docker install吗?
  • ¥15 cups交叉编译后移植到tina sdk的t113,只需要实现usb驱动打印机,打印pdf文件
  • ¥30 关于#wireshark#的问题:需要网络应用流量数据集需要做长度序列的实验,需要与应用产生的会话的数据包的长度,如视频类或者聊天类软件
  • ¥15 根据上述描述表示泥浆密度沿着管路的长度方向在不断变化,如何来表示泥浆密度随管路的变化(标签-matlab|关键词-流计算)