C11内存模型——两个线程执行atomic_fetch_add,然后执行atomic_load——可能输出什么?

2024-03-27

考虑以下测试程序,该程序在完全实现 C2011 原子和线程的实现上编译和运行。

#include <stdio.h>
#include <stdatomic.h>
#include <threads.h>

#if !ATOMIC_INT_LOCK_FREE
#error "Program behavior is only interesting if atomic_int is lock-free."
#endif

static atomic_int var;

int inc_print(void *unused)
{
   atomic_fetch_add(&var, 1);
   printf(" %d", atomic_load(&var));
   return 0;
}

int main(void)
{
    thrd_t thrd;
    if (thrd_create(&thrd, inc_print, 0) == thrd_success) {
        inc_print(0);
        thrd_join(&thrd, 0);
    }
    putchar('\n');
    return 0;
}

我已经设法说服自己以下所有陈述都是正确的:

  1. 每个线程的atomic_load必须观察同一线程执行的增量,因此它无法读取零。
  2. 每个线程的atomic_load可能会也可能不会观察到另一个线程执行的增量。 (另一个线程可能在atomic_load之后才被调度。)因此,它可以读取1或2。
  3. 致电printf已连载only互相对抗。因此,如果一个线程atomic_load读取 1 和另一个线程的atomic_load读取 2,或者1 2 or 2 1可以打印。
  4. 两者皆有可能atomic_loads 观察另一个线程执行的增量,因此输出2 2也是可以的。

但我不确定的是:是否有可能neither of the atomic_loads 观察另一个线程执行的增量?也就是说,是输出1 1可能的?

另外,放松记忆模型会改变什么吗?


你的结论对我来说看起来是正确的。

默认memory_order_seq_cst保证整个程序执行以顺序一致的方式 https://en.wikipedia.org/wiki/Race_condition#SC_for_DRF,因为它不存在数据争用并且不使用任何非 SC 原子。所以可能的结果只是程序顺序的交错。

这允许两个增量然后两个加载,但一个增量必须在另一个增量之后,看看它的1结果并写一个2。并且该线程中的负载必须在它之后,所以至少有一个线程看到2. The 1 1结果是不可能的,2 2结果可能会发生。


宽松原子不会在这里引入任何新的可能性;我们可以从操作规则中获得同样的保证same无论 memory_order 参数如何,都适用的原子变量。

  • 一致的修改顺序var存在,并且总共两个原子增量必须完成总共+=2。 (出于这个原因,原子 RMW 保证读取最新值,以确保同一对象上的 RMW 彼此序列化,而不是同时加载 0 和写入 1。这不会是原子增量。)
  • A load之后fetch_add在同一线程中必须看到其结果或修改顺序中的某个后续值。 (在 C++ 中这是读写一致性保证 https://eel.is/c++draft/intro.races#note-19,以及sequenced-before(在同一线程中)强制在两个操作之间进行排序same原子对象。欢迎编辑并提供 C11 标准中等效语言的链接。)

是的,printfs 的排序独立于原子修改var。它有效地锁定stdout。如果这像 C11 的规则一样有效mtx_lock,这就像一个acquire对互斥锁进行操作,因此它可以在增量或加载完成之前开始获取锁定。

并不是说那是相关的;这不是必需的2 1输出成为可能。即使锁定是seq_cst,您可能会进入这样一种状态:两个 printf 都没有开始,但所有原子都已完成。一个线程的临时值是 1,另一个线程的临时值是 2。那么首先打印的只是机会。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C11内存模型——两个线程执行atomic_fetch_add,然后执行atomic_load——可能输出什么? 的相关文章

  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • 在 WCF 上重用我的 PagedList 对象

    问题 我有一个自定义集合PagedList
  • 更新 Azure Blob 上的 LastModified

    我正在移植代码以使用 C 中的 Azure 存储 SDK 传统上 我称其为更新修改文件的上次写入 修改时间 File SetLastWriteTimeUtc fileName lastWriteTimeUtc 要更新 blob 的上次修改时
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 检测反射 DLL 注入

    在过去的几年中 恶意软件 以及一些渗透测试工具 如 Metasploit 的 meterpreter 负载 已经开始使用反射 DLL 注入 PDF http www harmonysecurity com files HS P005 Ref
  • ASP.NET MVC 动作过滤器

    有谁知道即使在 CATCH 块中 ActionFilterAttribute 类的 OnResultExecuted 方法是否也会执行 ie CookiesActions public ActionResult Login Usuarios
  • ASP.net WebForms - 在标记中使用 GetRouteUrl

    我一直在尝试弄清楚如何将路由功能与 ASP net 4 0 WebForms 一起使用 我将一条路线添加到我的路线集合中 void Application Start RegisterRoutes RouteTable Routes voi
  • 在 C# .NET 中对非 ASCII 字符进行编码

    我想向我的应用程序发送的电子邮件添加自定义标头 标头名称只能包含 ASCII 字符 但对于值和用户可能会输入 UTF 8 字符 我必须对它们进行 Base64 编码 此外 我还必须将它们解码回 UTF 8 以便在 UI 中向用户显示它们 最
  • 如何释放字符串未使用的容量

    我正在程序中处理很多字符串 这些字符串数据在读入我的程序后的整个生命周期内都不会改变 但由于 C 字符串保留了容量 因此浪费了大量肯定不会被使用的空间 我尝试释放这些空间 但没有成功 以下是我尝试过的简单代码 string temp 123
  • 如果仅使用第一个元素,是否必须为整个结构分配内存?

    我有一个结构 其中第一个元素被测试 并且根据其值 结构的其余部分将被读取或不会被读取 在第一个元素的值指示结构的其余部分不会被读取的情况下 我是否必须为整个结构或仅第一个元素分配足够的内存 struct element int x int
  • 使用任务的经典永无止境的线程循环?

    给出了一个非常常见的线程场景 宣言 private Thread thread private bool isRunning false Start thread new Thread gt NeverEndingProc thread S
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • Android,Volley请求,响应阻塞主线程

    使用 Volley 处理较大响应时会发生一些不好的事情 String url AppHelper DOMAIN service pages profile update json this infoTextView setText getS
  • Asp.Net Core 中的 SSL 不起作用

    我从 Visual Studio 创建了一个简单的 Web 应用程序Web Application Net Core 具有个人用户帐户授权的模板 然后 我启用了 SSLProject gt MyProject Properties 将带有
  • 在 LP2844Z(Zebra 打印机)上的收据中包含 PNG [重复]

    这个问题在这里已经有答案了 我正在致力于创建一个基于 HTML5 画布的签名 绘图框 目前我们在服务器上将画布保存为PNG 但可以轻松地将base64字符串保存在数据库中 现在的问题是我们如何在打印的收据上添加签名 目前我们使用 GF 字段
  • 创建进程默认浏览器

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 我想获取线程 id 因此 ShellExecute 无法获取线程 id 因此我开始使用

随机推荐