【问题标题】:Is int safe to read from multiple threads?从多个线程读取 int 是否安全?
【发布时间】:2011-11-27 01:36:37
【问题描述】:

我有多个线程读取相同的 int 变量。 一个线程正在写入值。

我不关心比赛条件。

只有我关心的是同时写入和读取 int 值是否内存安全?

它不会导致任何应用程序崩溃。

【问题讨论】:

标签: c linux multithreading gcc pthreads


【解决方案1】:

在我所知道的所有 Linux 平台上,对齐 int 的读取和写入都是原子且安全的。您永远不会读取未写入的值(无字撕裂)。您永远不会导致故障或崩溃。

【讨论】:

  • 我认为这种宽泛的说法确实需要参考。此外,在这种情况下,对齐的确切含义是什么
  • 如果有人不知道对齐整数是什么,那么他们就没有必要编写多线程程序了。
  • 哦,真迷人。此外,方式过于笼统。好吧,当然,你不需要打扰。关于 SO 的其他答案更能说明问题。
  • 代码可以获得变量的陈旧值。例如,如果它来自寄存器(因为代码优化)。
  • @Shamit:没错。 OP 说他不关心比赛条件。
【解决方案2】:

是的,在 x86 和 x86-64 上,只要您读取的值正确对齐。 32 位 ints,它们需要在 4 字节边界上对齐,以便在读取或写入时访问为 atomic,除非您不遗余力地创建未对齐的,否则几乎总是如此ints(例如,通过使用压缩结构或使用字节缓冲区进行强制转换/指针运算)。

您可能还希望将变量声明为volatile,以便编译器生成代码,每次访问该变量时都会从内存中重新获取该变量。这将阻止它进行优化,例如当它可能被另一个线程更改时将其缓存在寄存器中。

【讨论】:

  • +1 表示易失性,实际上提到了对齐模数
【解决方案3】:

是的,应该没问题。我可以设想崩溃的唯一方法是如果其中一个线程取消分配支持该整数的内存。为了获得最佳结果,我还将确保整数在sizeof(int) 边界处对齐。 (有些 CPU 在没有这种对齐方式的情况下根本无法访问整数。其他 CPU 为未对齐访问提供较弱的原子性保证。)

【讨论】:

  • 确保整数在 sizeof(int) 对齐,您能否提供更多信息,我该怎么做?
  • @VivekGoel 在大多数情况下,您的编译器会为您完成。但是有编译器特定的方法可以实现这一点,即__attribute__((aligned(4))) for GCC。
  • @VivekGoel - 你也可以在运行时检查这个,即((uintptr_t)&x) % sizeof(int) 应该为零。 (您甚至可以为此添加assert。)
  • @asveikau 对于 gcc 更便携应该是 __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)))
  • @user411313 +1。我这里只写了4个作为例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多