C语言中的原子交换指针
我需要线程将堆上的数据结构报告给控制线程(星形拓扑)。我不想为此使用锁,而是通过原子地交换指向此数据结构的指针来实现这一点。因此,我有一个报告的set-and-get方法C语言中的原子交换指针,c,atomicity,C,Atomicity,我需要线程将堆上的数据结构报告给控制线程(星形拓扑)。我不想为此使用锁,而是通过原子地交换指向此数据结构的指针来实现这一点。因此,我有一个报告的set-and-get方法 static atomic_uintptr_t aptr = ATOMIC_VAR_INIT((uintptr_t)NULL); void set_report(void *newreport) { // swap the report pointer atomically uintptr_t prev =
static atomic_uintptr_t aptr = ATOMIC_VAR_INIT((uintptr_t)NULL);
void set_report(void *newreport)
{
// swap the report pointer atomically
uintptr_t prev = atomic_exchange( &aptr, (uintptr_t)newreport);
// if prev is not NULL we need to destroy it
if ( prev != (uintptr_t)NULL )
{
// destroy the memory it is pointing to
free((void *)prev); // there seems to be no way of avoiding a compiler warning here
// about casting to a non-matching type :S
}
}
uintptr_t get_report()
{
// swap the report pointer atomically with NULL
uintptr_t report = atomic_exchange( &aptr, (uintptr_t)NULL);
// we now own report so the caller must destroy when finished with it
// unless it's null of course
return report;
}
我可以这样使用代码:
int *bla = (int*)calloc(1, sizeof(int));
*bla = 3;
set_report((void *)bla);
int *v = (int *)(void *)get_report();
我几乎找不到任何关于使用带指针的原子的参考资料或文档,因此我对这段代码有一些疑问:
- 在C中以原子方式进行指针交换时,这是正确的方法吗
- 从我读到的内容来看,当使用指针的原子方法(gcc stdatomic.h)时,我需要使用uintptr\t。但我无法回避有关强制转换为不匹配类型的警告。我应该忽略这些吗
- “aptr”是否需要声明为易失性
(uintpttr\t)NULL
需要(uintptpr\t)(void*)NULL
才能实现最大的可移植性。对于不匹配的类型,您会得到什么警告?我没有看到gcc使用标志-Wall-Wextra-pedantic
“在C中以原子方式进行指针交换时的正确方式”-->的任何警告。请注意,uintptr\u t
是可选类型。函数指针的代码可能会失败,但这里似乎只使用分配的指针。您使用的编译器是什么?@roberts-supportsmonicacellio-NakedNULL
由于其类型不确定(可能是void*
,int
,long
等),因此总是有点棘手(void*)NULL
当然是一个空指针。OP需要一个uintptr\t
版本的空指针,而不是null
。此外,转换为uintptr\t
的空指针不一定为0。IAC,尝试通过uintpttr\t
转换进行指针比较,然后进行整数数学比较,通常“有效”,但未指定按需要执行。我怀疑一个\u原子空洞*
是最好的方法,放弃所有uintpttr\u t
东西。