首页 > 解决方案 > 扩展内存分配,如果不可能则失败

问题描述

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

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

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

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

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

目前,我使用一种解决方法,即 to malloc, memcpy, 然后free使用信号量来确保所有线程在调用free它之前都已移至新分配。

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

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

标签: cmemory-managementconcurrencyrealloc

解决方案


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

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

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


推荐阅读