c - CAS for c、openmp的实现
问题描述
我正在尝试实现比较和交换操作,以便我的线程知道是否基于 value 进入特定区域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 操作后我仍然看到其他线程进入这个区域?
解决方案
我正在尝试实现比较和交换操作
您不能在 C 中实现它。这样的操作必须是原子的,才能有意义地用于线程之间的同步目的。注意序列点和内存模型。
一些编译器为此提供了内置函数。(另见这个问题)。最近的 GCC 提供了原子内置指令,包括__atomic_compare_exchange
通常编译成单个机器代码指令的指令。阅读关于比较和交换的维基页面
在 Linux 上,还要注意futex(7)。对于像CMPXCHG这样的机器指令,它们是许多pthreads(7)操作的构建块(因此需要一些汇编代码)。另请阅读一个很好的pthread 教程。C11 标准(阅读n1570)提供<stdatomic.h>
(实际上,标准原子操作是编译器内置的,或使用现有的内置)。
还要研究现有自由软件C 标准库的源代码,例如 GNU glibc或musl-libc。您会看到许多同步原语是在 futex、汇编代码和/或编译器内置函数之上构建的。
此外,OpenMP(当它由编译器实现时)正在改变编译器的行为(当然还有生成的可执行文件)。
推荐阅读
- node.js - 从前端应用程序调用时,Express Gateway(启用密钥身份验证)给出 COR 问题
- ssis - 有没有办法让子包独立写入catalog.operation_messages?
- sql - 时间序列数据的星型模式多对多
- docker - 如何在heroku中公开一个端口?
- spring-el - 使用 SPEL 解析 XML 消息
- visual-studio-code - 在 vscode 提供的 WebView 中播放声音
- r - 如何对 tfdatasets r 中的响应变量进行一次热编码?
- reactjs - 开玩笑的全局变量模拟
- php - Ajax 调用重载消息
- amazon-web-services - Alexa智能家居技能开发:设备发现不起作用