【问题标题】:Free memory atomically原子地释放内存
【发布时间】:2018-07-30 20:53:48
【问题描述】:

这是一个函数,我用来释放动态分配的内存

void Free(void* arg) {
    if(arg!=NULL) {
        free(arg);
        arg=NULL;
    }
}

到目前为止,它工作正常,直到我开始使用 pthreads。我的堆栈不时被破坏,我唯一能做的就是使用 pthread_mutex_lock()
是否有任何原子公告来检查和释放 gcc 中的内存?
或者您可以提出另一个解决方案吗?我希望互斥锁不是唯一的方法

【问题讨论】:

  • 什么操作系统?在 Linux 上,mallocfree 在内部使用互斥锁。
  • 你应该阅读free的文档。它可以很好地处理NULL 本身。而且由于您所修改的只是将其设置为 NULL 的局部变量……老实说,这是一个毫无意义的函数。
  • 如果你想分配一个块,让所有线程使用同一个块,然后让所有线程在完成后“释放”块,然后 a) 不要那样做,b) 使用互斥保护的引用计数。 c) 不要这样做,除非你完全没有办法通过重新设计来避免它。
  • @MartinJames 当然,您也可以在程序的主线程中allocatefree 这样的块。我认为这里的主要问题也是设计。应该有明确的内存块所有权。如果它是跨线程共享的,那么它属于程序,并且应该只在主程序确定所有线程都已完成执行后才free()ed。
  • 你为什么“希望互斥锁不是唯一的方法”,如果需要同时访问数据,那么一个简单的方法就是使用互斥锁,并且根据某些事情,这是一个完全可以接受的解决方案。但也许,有些“某些事情”让你担心,对吧?

标签: c memory-management pthreads


【解决方案1】:

mallocfree 函数在内部使用互斥锁来确保正确管理堆。但是,这并不能防止您的应用程序尝试从多个线程读取/写入变量。

每当读取或写入两个或多个线程有权访问的变量时,您需要使用互斥锁来保护该访问。否则,您最终会出现不一致的状态,并且您无法预测程序的行为。

附带说明,您编写的函数不会将传入的指针设置为 NULL。它所做的是将一个局部变量设置为 NULL,这对调用函数是不可见的。为此,它需要接受void **:

void Free(void **arg) {
    if(arg!=NULL) {
        free(*arg);
        *arg=NULL;
    }
}

并被这样称呼:

Free((void **)&ptr);

这是使用宏实际上更简洁的情况之一:

#define Free(arg) do { free(arg); (arg) = NULL; } while (0)

【讨论】:

  • 或者更好void *p = *arg; *arg = NULL; free(p);
  • 好吧,如果是相关线程从未写入的配置数据,那么锁定它是没有意义的。
  • @Rarity 只是为了避免这个问题的出现而设计。如果它永远不会发生,你就不需要找到创造性的方法来保证它可能会或可能不会可靠地工作:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 2023-04-10
  • 2015-07-18
  • 1970-01-01
相关资源
最近更新 更多