c - 指针解引用线程安全吗?

标签 c multithreading pointers mutex

我已经实现了堆内存管理,现在我不确定两点(在代码后解释):

所以堆内存管理基本上是这样实现的:

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/

相关文章:

c++ - 在线程内使用全局数组

c - 意外的堆栈粉碎

python - 了解 os.fork 和 Queue.Queue

c++ - 为什么在指向对象的指针上调用方法与在对象本身上调用方法具有不同的行为?

go - go 中的 reflect.ValueOf() 和 Value.Elem() 有什么区别?

objective-c - 深入了解 Objective-C 中强指针和弱指针的实际应用

c - C 字符串中的 %d 个指针到整数的转换?

c - zlib 函数找不到的符号

Python多线程基础混淆

java - 如何将下面的示例转换为实现 Runnable 接口(interface)并重写 run 方法