【问题标题】:C - Freeing data structures in threads?C - 释放线程中的数据结构?
【发布时间】:2017-02-27 06:07:32
【问题描述】:

我刚刚在 C 中创建了一个 LinkedList,我有一个 clear 函数。

clear 函数遍历 LinkedList 并在每个节点上调用 free()。这意味着它是一个O(n) 函数,非常慢。

我是否应该创建一个pthread(或其他一些我不知道的线程库),提供我的root 节点,将我的LinkedList 的root 节点设置为NULL,然后清理线程现在可以立即添加列表时的内存?这样做有危险吗?这意味着用户可以在有足够的空间来解释之前向 LinkedList 添加更多数据,对吗?它就像一张信用卡,但用于记忆。

这样做安全吗?在这种情况下,如何编写健壮且快速的代码?

【问题讨论】:

  • “……很慢。” - 相比什么?当然,您似乎认为的内存泄漏通常更快。说:不清楚你在问什么。提供包含所有必需信息的minimal reproducible example
  • 链接列表通常表现不佳,而不是因为释放。如果没有基准、参考机器和性能要求,这个问题是无法回答的。
  • 在我看来这是清除整个链表的唯一方法。 “将我的 LinkedList 的根节点设置为 NULL,然后让线程清理内存”如果您丢失了 root 节点,您如何访问其他节点?
  • @Olaf 如果我使用thread 来清除 LinkedList,那么可能正在使用 LinkedList 的主线程...队列不必等待 O(n)手术。意思是,您可以将n 元素添加到LinkedList,调用clear(这是O(n))并且您的主线程永远不必循环主列表。它节省了一个额外的循环O(n)
  • @Mouin 我会将rootNode 传递给垃圾清理线程,但在LinkedList struct 中我会将root 设置为NULL,这样操作就像insert、@ 987654338@等都会假定LinkedList是空的。

标签: c multithreading data-structures


【解决方案1】:

当然,如果你用 pthread 编译,那么 free 应该是线程安全的。

安全吗?使用互斥锁确保访问受到保护,不会被并发编辑。

你应该这样做吗?将线程隐藏在常见的容器结构后面被认为是糟糕的架构风格。您的图书馆用户会认为 clear() 是一种可以完成工作的阻塞方法。如果库用户需要异步释放,他可以自己 fork 一个线程。

链表是否必须具有 O(n) 时间复杂度?如果所有内存都在托管的连续块中,则并非如此。

【讨论】:

  • 在写你的答案之前,我正要写一个答案。我只会补充一点,他不会提高速度,而是会因创建线程、等待锁定等而产生开销……即使有 2 个或更多线程,最终也会作为单个执行单元。
  • 问题更多的是,我应该使用线程来清除任何数据结构的内存还是应该只使用我所在的线程并在主线程的 O(n) 中清除它们.
【解决方案2】:

我认为将clear 任务分布在多个线程上并不是一个好主意。

我想问题是你有一个主线程调用clear 以获得一个长列表(需要时间来清除)并且因为clear 函数没有返回而被阻塞。在这种情况下,使用一个主线程和另一个线程“垃圾收集器”可能会很好,它一直等到收到clear 命令并开始释放内存。

使用 2 个线程可以帮助您避免阻塞调用者,希望我能理解您的问题

【讨论】:

  • 嗯等等我可能有点困惑。为什么主线程要等待清除线程完成?主线程不应该只是启动清理线程并继续它的业务吗?
  • @Hatefiend,clear函数是一个while循环,在链表节点上调用free,所以调用clear会导致调用者阻塞。
  • 是的,但想法是这样的:你将root Node 的引用传递给清理线程。它使用Node 来遍历和清除。同时回到主线程,将LinkedListstructroot 属性设置为NULL,这样就好像列表中的旧项目永远消失了。您将列表的size 设置为0,就像您在主线程的O(1) 速度和清理线程的O(n) 速度中清除了整个列表。不涉及等待对吗?除非我弄错了?
  • @Hatefiend,好的,我不明白,之后您面临的问题是什么?,我正在考虑您clear 您的列表并再次开始插入节点之后的情况。在这种情况下,如果您使用动态分配(malloc)来创建节点,则没有问题,因为 malloc 将搜索空闲空间,并且释放和分配的空间之间没有并发性。但是,如果您使用静态分配(您的列表是静态数组),那么当您的 clear 线程尝试清除主线程尝试分配的节点时,您可能会遇到并发问题,在这种情况下,您必须使用互斥锁
  • 只是一个问题,你为什么需要它是为了学习还是你正面临一个真正的问题?
猜你喜欢
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2011-02-26
相关资源
最近更新 更多