我已经实现了堆内存管理,现在我不确定两点(在代码后解释):
所以堆内存管理基本上是这样实现的:
struct memory {
// Mutex for thread safe operations
pthread_mutex_t _mutex;
// Memory size
size_t _size;
};
int allocMemory(void **memoryPointer, const size memorySize)
{
void *memory;
struct memory *internal;
/* Checking arguments... */
memory = malloc(memorySize + sizeof(struct memory));
if (memory == NULL) return ENOMEM;
internal = (struct memory *)memory;
pthread_mutex_init(&internal->_mutex);
internal->_size = memorySize;
// Set pointer with offset
*memoryPointer = memory + sizeof(struct memory);
return 0;
}
int reallocMemory(void **memoryPointer, const size newMemorySize)
{
/* Checking arguments... */
{
void *memory;
void *memoryWithoutOffset;
struct memory *internal;
// Get pointer v--- is this thread safe?
memory = *memoryPointer;
// Subtract offset
memoryWithoutOffset = memory - sizeof(struct memory);
// Get internal data (for _mutex)
internal = (struct memory *)memoryWithoutOffset;
pthread_mutex_lock(&internal->_mutex);
{
void *newMemory;
newMemory = realloc(memoryWithoutOffset, sizeof(struct memory) + internal->_size + newMemorySize);
if (newMemory != NULL) {
// Refresh pointer to "internal" because its location may have been changed
internal = (struct memory *)newMemory;
internal->_size += newMemorySize;
// Add offset
*memoryPointer = newMemory + sizeof(struct memory);
}
}
pthread_mutex_unlock(&internal->_mutex);
}
return 0;
}
在我的主文件中,我有这样的内容:
void *myMemory;
void *threadFunction(void *arg)
{
// v--- reference to `myMemory`
reallocMemory(&myMemory, 100);
return NULL;
}
int main(int argc, const char **argv)
{
pthread_t thread;
allocMemory(&myMemory, 10);
/* ... */
for (int i = 0; i < 5; ++i) {
pthread_create(&thread, NULL, threadFunction, NULL);
}
/* ... joining threads etc. */
return EXIT_SUCCESS;
}
我的问题是,在锁定互斥锁之前,我必须从给定的指针引用中“提取”它。这个指针解引用是否会破坏线程安全? 内存 = *内存指针
这种“隐藏”指针中的结构是安全/良好的做法吗?
顺便说一句:我已经用 valgrind
对其进行了测试,它没有显示无效的读取或写入。
感谢您的帮助...
最佳答案
不,它不是线程安全的。考虑两个线程都有一个指向 myMemory 的指针,如果一个线程重新分配 myMemory,另一个线程如何知道它的 myMemory 指针现在无效(重新分配可能会移动内存块)。
您可能需要考虑采用固定位置结构,例如:
struct memory {
pthread_mutex_t _mutex; // Mutex for thread safe operations
size_t _size; // Memory size
void *memory_ptr; // pointer to memory
};
然后使用(伪代码)等函数分配、重新分配和访问内存:
alloc_memory()
malloc struct memory
memory_ptr= malloc memory reqd
fill in memory struct
reallocMemory( struct memory *, new_size )
obtain mutex
reallocate memory pointed to by memory_ptr
release mutex
void * start_access_memory( struct memory *)
obtain mutex
return memory_ptr
end_access_memory( struct memory *)
release mutex
这样每个线程都可以有一个指向内存结构及其互斥体的持久指针。
关于c - 指针解引用线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22284318/