gpt4 book ai didi

c++ - 我需要用锁来保护这个变量吗?

转载 作者:可可西里 更新时间:2023-11-01 17:04:28 25 4
gpt4 key购买 nike

所以我在多处理器机器上有一个 C++ bool 类型。变量开始时为真,然后有几个线程,其中任何一个或多个线程都可能将其写入为假。

同时,这些线程也可能读取这个变量来检查它的状态。我不关心读取这个变量是否与任何写入同步,它们各自发生在代码的不同位置,并且它是在任何特定写入之前还是之后都没有关系。现在,我需要为这个 bool 值加锁吗?

我需要锁的唯一方法是,如果在非常低的级别,内存可能会被两个竞争写入破坏。例如,如果处理器 A 上的汇编指令正在将 0 写入表示 bool 值的字节,同时处理器 B 也在做同样的事情......而不是写入 0,内存最终值为 22 或某物。那可能会把事情搞砸。

所以,一般来说,如果进程 A 正在将 3 写入内存位置,而进程 B 正在写入 7,并且没有同步,我是否保证至少会得到 3 或 7?还是有那么容易断掉内存?

编辑:

谢谢大家的评论。更多信息:程序中当然有同步。总而言之,有问题的标志告诉某个内存池是否“脏”(需要压缩)。因此,任何线程都可以决定将此标志设置为 false(意味着池是脏的)。例如,从池中释放内存会使它变脏。然后任何线程也可以读取这个标志并设置另一个标志来表示需要清理——这个检查是在从池中分配内存时完成的,如果内存不足,就会发出清理信号。在迭代之间我的主关键部分的某个地方,每个线程都去寻找更多的数据来处理,我会让线程检查第二个标志,并做一些适当的事情来确保:所有其他线程完成他们当前的迭代,一个线程清理内存,将第一个标志设置回 true(因为池中没有脏),将第二个标志设置回 false,然后再次释放所有线程。

所以我认为我不需要锁,因为:锁可以确保写入不会与另一个写入或读取同时发生。但是谁在乎,只要硬件不会让我失望,最坏的情况是读取在写入之前或之后随机发生——这与我用锁保护它会发生的事情是一样的,就在那时我们真的确定它是在...之前或之后出现的

我认为同样的论点适用于我上面提到的第二个标志。

最佳答案

在大多数商用硬件上,单个字的读/写是原子的,因此不会,两个(或更多)对同一内存位置的竞争写入(和读取)不会破坏该值。这里重要的是 CPU 之间的缓存一致性

同样,在商用硬件上,您可能只需标记单个 bool 变量 volatile(顺便说一下,它已被声明对并发编程无用)以防止编译器将其优化到寄存器中,< strong>但前提是您真的不关心写入的顺序。

让我用 list 重申一下:

  • 您准备好丢失该 bool 值的一些更新了吗?
  • 您确定源代码中 bool 翻转之前但可能在翻转之后重新排序的其他内存更新不会把事情搞砸吗?
  • 您确定不关心应用程序中事件的顺序吗?

如果您有三个强有力的"is"答案,您可能可以不保护该标志而逃脱惩罚。仍然考虑在读取变量之前插入acquire memory barrier,在写入变量之前插入release memory barrier。不过,我的建议是重新考虑设计,并制定清晰的同步线程间通信和事件排序。

希望这对您有所帮助。

关于c++ - 我需要用锁来保护这个变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3225223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com