C 指针解引用线程安全吗?

C 指针解引用线程安全吗?,c,multithreading,pointers,mutex,C,Multithreading,Pointers,Mutex,我已经实现了堆内存管理,现在有两点我不确定(在代码后面解释): 因此,堆内存管理基本上是这样实现的: struct内存{ //用于线程安全操作的互斥锁 pthread_mutex_t_mutex; //内存大小 大小(t)大小;; }; int allocMemory(无效**内存指针,常量大小内存大小) { 空*内存; 结构内存*内部; /*正在检查参数*/ 内存=malloc(memorySize+sizeof(struct memory)); if(memory==NULL)返回ENOME

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

因此,堆内存管理基本上是这样实现的:

struct内存{
//用于线程安全操作的互斥锁
pthread_mutex_t_mutex;
//内存大小
大小(t)大小;;
};
int allocMemory(无效**内存指针,常量大小内存大小)
{
空*内存;
结构内存*内部;
/*正在检查参数*/
内存=malloc(memorySize+sizeof(struct memory));
if(memory==NULL)返回ENOMEM;
内部=(结构内存*)内存;
pthread\u mutex\u init(&internal->\u mutex);
内部->\u大小=内存化;
//用偏移量设置指针
*memoryPointer=memory+sizeof(结构内存);
返回0;
}
int reallocMemory(void**memoryPointer,常量大小newMemorySize)
{
/*正在检查参数*/
{
空*内存;
无效*无偏移的内存;
结构内存*内部;
//获取指针v---此线程安全吗?
内存=*内存指针;
//减去偏移量
memoryWithoutOffset=内存-sizeof(结构内存);
//获取内部数据(用于_互斥)
内部=(结构内存*)内存,不带偏移量;
pthread_mutex_lock(&internal->_mutex);
{
空*新记忆;
newMemory=realloc(memorywhithoutoffset,sizeof(struct memory)+internal->\u size+newMemorySize);
if(newMemory!=NULL){
//刷新指向“内部”的指针,因为其位置可能已更改
内部=(结构内存*)新内存;
内部->\u大小+=新建内存大小;
//添加偏移量
*memoryPointer=newMemory+sizeof(结构内存);
}
}
pthread_mutex_unlock(&internal->_mutex);
}
返回0;
}
在我的主文件中,我有如下内容:

void*myMemory;
void*threadFunction(void*arg)
{
//v---myMemory的引用`
reallocMemory(&myMemory,100);
返回NULL;
}
int main(int argc,常量字符**argv)
{
pthread\u t线程;
allocMemory(&myMemory,10);
/* ... */
对于(int i=0;i<5;++i){
pthread_create(&thread,NULL,threadFunction,NULL);
}
/*…连接螺纹等*/
返回退出成功;
}
我的问题是,在锁定互斥锁之前,我必须从给定的指针引用中“提取”互斥锁。这个指针取消引用会破坏线程安全吗<代码>内存=*内存指针

在指针中“隐藏”结构是一种安全/良好的做法吗

顺便说一句:我用
valgrind
对它进行了测试,它没有显示任何无效的读写


感谢您的帮助…

不,它不是线程安全的

两个线程可以同时访问内存位置
myMemory
,并且至少有一个操作是写访问。这被称为数据竞争,C11指出,具有数据竞争的程序具有未定义的行为——与C++11中的行为完全相同

两条相关线路为:

  memory               = *memoryPointer;
  *memoryPointer = newMemory + sizeof(struct memory);

必须为变量
myMemory
使用原子变量。不幸的是,AFAIK GCC-4.7不支持C11。不,它不是线程安全的

两个线程可以同时访问内存位置
myMemory
,并且至少有一个操作是写访问。这被称为数据竞争,C11指出,具有数据竞争的程序具有未定义的行为——与C++11中的行为完全相同

两条相关线路为:

  memory               = *memoryPointer;
  *memoryPointer = newMemory + sizeof(struct memory);

必须为变量
myMemory
使用原子变量。不幸的是,AFAIK GCC-4.7不支持C11。不,它不是线程安全的。考虑两个线程,一个指向内存的指针,如果一个线程重新分配了内存,另一个线程如何知道我的内存指针现在是无效的(ReLoLc可以移动内存块)。 <>你可能想考虑有一个固定的位置结构,比如:

struct memory {
     pthread_mutex_t _mutex;    // Mutex for thread safe operations
     size_t _size;              // Memory size
     void *memory_ptr;          // pointer to memory
};
然后使用(伪代码)等函数分配、重新分配和访问内存:


这样,每个线程可能都有一个指向内存结构及其互斥体的持久指针。

不,它不是线程安全的。考虑两个线程,一个指向内存的指针,如果一个线程重新分配了内存,另一个线程如何知道我的内存指针现在是无效的(ReLoLc可以移动内存块)。 <>你可能想考虑有一个固定的位置结构,比如:

struct memory {
     pthread_mutex_t _mutex;    // Mutex for thread safe operations
     size_t _size;              // Memory size
     void *memory_ptr;          // pointer to memory
};
然后使用(伪代码)等函数分配、重新分配和访问内存:


这样,每个线程可能都有一个指向内存结构及其互斥体的持久指针。

首先感谢您的回答!将
void**memoryPointer
更改为
void*memory
并返回新指针会使其线程安全吗?@d3l:这取决于具体情况。函数的调用者是否会写入
myMemory
?这并不能解决数据竞争问题。如果调用者不写信给它,会是吗?或者调用方何时使用全局互斥锁进行写入?@d3l:如果变量
myMemory
只写入一次(在任何其他线程尝试读取它之前),那么它是线程安全的。否则,变量
myMemory
必须是原子的,或者读取必须以某种方式与写入同步。这意味着,如果使用互斥锁进行写入,这是不够的。读取也必须使用互斥锁。谢谢,我现在明白了。:)首先谢谢你的回答!将
void**memoryPointer
更改为
void*memory
并返回新指针会使其线程安全吗?@d3l:这取决于具体情况。函数的调用者是否会写入
myMemory
?这并不能解决数据竞争问题。如果调用者不写信给它,会是吗?或者调用方何时会使用全局互斥锁进行写入?@d3l:如果变量
myMemory
只写入一次(bef