【问题标题】:Extend memory allocation, fail if not possible扩展内存分配,如果不可能则失败
【发布时间】:2020-10-12 17:42:43
【问题描述】:

我正在编写一个并行程序,在该程序中我必须重新分配一个内存块,该内存块正在被其他线程主动写入。执行此操作的自然方法是使用realloc,但是在并行写入的块上调用realloc 时,有两种可能的结果:

  1. realloc 能够扩大分配。没有问题发生。
  2. realloc 必须创建新分配,将旧分配的内容复制到新分配,并释放原始分配。

第二种情况有问题有两个原因:

首先,因为初始分配中的一个字节可以被写入之后该字节已被复制和realloc 返回之前。在这种情况下,一旦旧的分配被释放,写入将丢失。

其次,因为realloc 将在旧分配返回之前释放它,因此同时访问该内存区域的其他线程将读取释放的内存,这不能保证是安全的。

目前,我使用一种解决方法,即到mallocmemcpy,然后是free,并使用信号量确保所有线程都已移至新分配,然后再调用free

但是,这种方法放弃了 realloc 的主要优点——如果有空间可以扩展分配。所以,我的问题是extend_allocation 是否有某种方法可以扩展分配或失败(在这种情况下我可以回退到 malloc/memcpy/free),或者我是否必须使用 malloc/memcpy/free时间?

我们也欢迎对有解决此问题的替代内存分配器的建议作为答案。

【问题讨论】:

    标签: c memory-management concurrency realloc


    【解决方案1】:

    如果你真的想使用realloc,你需要在可能修改指针之前序列化对指向已分配内存的指针的访问。

    内存指针应该是全局的,因此任何线程都可以访问它,以及关联的互斥锁或信号量。每当一个线程想要使用指针来读取或写入值时,它首先需要锁定互斥体,然后在完成后解锁它。

    一旦你有了这个地方,你就可以通过锁定互斥体,调用realloc,然后解锁它来轻松地增加内存。

    【讨论】:

    • 是的,这个答案是正确的(我认为做你建议的最有效的方法是读写锁),但我认为 malloc/memcpy/free 会更高效因为其他线程访问永远不需要旋转。不过,我必须进行基准测试,感谢您抽出时间来回答。
    • @thesecretmaster 是的,读/写锁可能会更高效。另外,您在调用mallocmemcpyfree 之间有没有做任何事情?因为如果不是,那与realloc 基本相同。
    • 嗯,memcpy 有点简化。有一个过渡期,其他线程开始使用新分配,如果他们需要的数据不在新分配中,则回退到旧分配,而旧分配中的数据在逻辑上被复制到新分配。然后,一旦所有数据传播完毕,旧的分配就会被释放。但是,如果我可以延长分配,就可以避免这种过渡状态。
    猜你喜欢
    • 2018-10-02
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2016-05-01
    • 2013-02-19
    • 2011-12-12
    相关资源
    最近更新 更多