为c,openmp实现CAS

时间:2018-11-05 03:35:58

标签: c multithreading openmp

我正在尝试实现比较和交换操作,以便我的线程基于值u_parent知道是否要进入特定区域。我只想知道这是否是实现它的正确方法,以及我是否在某处出错。

int *u_parent;
u_parent = &graph->parents[u]; 

if (*u_parent < 0) { 
    // This region should only be entered by each thread
    // if the value of u_parent is < -1.   

    graph->parents[u] = v;
    // ^-- If region is entered, this value is modified
    // by some variable v

    //Swap:
    u_parent = &graph->parents[u];

    DO_SOMETHING();
}

此实现是否正确,因为在执行CAS操作后仍然看到其他线程进入该区域?

1 个答案:

答案 0 :(得分:4)

  

我正在尝试执行比较和交换操作

不能在C语言中实现该操作。必须进行atomic这样的操作才能有意义地用于线程之间的同步。请注意sequence pointsmemory models

某些编译器为此提供了一个内置函数。 (另请参阅this问题)。最近的GCC提供了atomic builtins,其中包括__atomic_compare_exchange,这些 implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'com.squareup.retrofit2:converter-gson:2.3.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' 通常被编译成单个机器代码指令。阅读compare-and-swap

上的维基页面

在Linux上,还要注意futex(7)。使用CMPXCHG之类的机器指令,它们是许多pthreads(7)操作的构造块(因此需要一些汇编代码)。另请阅读优质的pthread tutorial。 C11标准(读为n1570)提供了<stdatomic.h>(实际上,标准的原子操作内置于编译器中,或使用现有的内置物)。

还要研究现有free software C标准库的源代码,例如GNU glibcmusl-libc。您会看到许多同步原语是在futex,汇编代码和/或编译器内置文件之上构建的。

此外,OpenMP(由编译器实现时)正在改变编译器(当然还有生成的可执行文件)的行为。