Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的原子交换指针_C_Atomicity - Fatal编程技术网

C语言中的原子交换指针

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 =

我需要线程将堆上的数据结构报告给控制线程(星形拓扑)。我不想为此使用锁,而是通过原子地交换指向此数据结构的指针来实现这一点。因此,我有一个报告的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 = 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”是否需要声明为易失性

Pedantic:我怀疑
(uintpttr\t)NULL
需要
(uintptpr\t)(void*)NULL
才能实现最大的可移植性。对于不匹配的类型,您会得到什么警告?我没有看到gcc使用标志
-Wall-Wextra-pedantic
“在C中以原子方式进行指针交换时的正确方式”-->的任何警告。请注意,
uintptr\u t
是可选类型。函数指针的代码可能会失败,但这里似乎只使用分配的指针。您使用的编译器是什么?@roberts-supportsmonicacellio-NakedNULL由于其类型不确定(可能是void*intlong等),因此总是有点棘手
(void*)NULL
当然是一个空指针。OP需要一个
uintptr\t
版本的空指针,而不是
null
。此外,转换为
uintptr\t
的空指针不一定为0。IAC,尝试通过
uintpttr\t
转换进行指针比较,然后进行整数数学比较,通常“有效”,但未指定按需要执行。我怀疑一个
\u原子空洞*
是最好的方法,放弃所有
uintpttr\u t
东西。