当前位置: 首页 > 知识库问答 >
问题:

同时写入一次和读取多次…没有锁定[关闭]

夏侯弘量
2023-03-14

这是一个关于一个作者和多个同时的读者的问题。

我希望这会激怒一些羽毛,我可能会因为胆敢问这个问题而被否决,但我想知道它是如何运作的。我知道互斥和原子是什么,没必要教我。

假设我有一个可供多个线程访问的内存位置(一个全局变量,或者我共享的一个指针)它的大小与体系结构相同,假设它是64位系统中8字节大小的单个无符号整数。它被设置为0

假设我有一千个线程在循环中读取它。如果它的0他们做一些重要的事情,如果它的1他们做另一件重要的事情,如果它既不0也不1他们发射核导弹。

然后一个线程(正好是一个,而不是多个)用值1覆盖此内存位置。会发生什么?

参见...我的理论是没有坏事发生,这是好的。没有数据损坏。在01之间没有半路。一个循环显示0,下一个循环显示1。不需要互斥或原子。我说的对吗?如果不是,为什么?

编辑:系统要求我解释为什么这和另一个问题不一样。答案是因为它和那个问题不一样。如果你不确定它有什么不同,请再读一遍,特别是以问号结尾的部分。

共有2个答案

何兴学
2023-03-14

线程通常不直接从内存读/写,而是读/写到它们的缓存。缓存是一个较小但速度快得多的内存。

要让一个读取器线程读取1而不是0,首先需要执行两件事:

  1. 写入程序线程必须已将其缓存写回内存。
  2. 读取器线程必须已从内存重新加载其缓存。

这些事件何时发生,取决于体系结构、OS、其他进程和您的代码。

您的每个读取器线程将读取0直到它们读取1。从0到1的切换可能根本不会发生,它可能发生在不同的线程的不同时间。

这就是原子的作用,它们可以在不同线程的缓存中强制同步。

党佐
2023-03-14

然后一个线程(正好是一个,而不是多个)用值1覆盖这个内存位置。会发生什么?

参见...我的理论是没有坏事发生,这是好的

你搞错了。

如果一个线程写入一个内存位置,而您没有任何同步机制,也没有使用原子,那么您就无法保证其他线程会看到更改。

variable=1;下运行着一整堆技术,几乎每一层都可以吞噬这个更新。

在程序集级别和CPU级别,不存在强制从1级缓存写回主内存的情况。

如果你只有一个变量和一个变化,这也不是太糟。有些线程会看到更新的值,有些则不会。更新传播可能需要很长的时间。你仍然可以称之为最终的一致性。

但一旦有了两个变量,写入值和读取值之间就会出现不一致。

把“内存模型一致性C++”放在你最喜欢的搜索引擎中了解更多细节。

 类似资料:
  • 我是Spring Batch的新手。我的要求是我有一个阅读器,它通过Web服务调用/数据库调用获取记录,目前我正在将这些记录写入一个表。现在我需要处理相同的记录(阅读器读取的记录)并写入另一个表。这里要注意的一点是,第二次写入中存储的第二个项目是不同类型的第一次写入。 我需要像下面这样 对于上述相同的工作,我需要事务管理。此外,在步骤2中:-如果可能,我应该使用步骤1中已经读取的数据。

  • 我正在尝试使用react-native-NFC-Manager在我的react-本机应用程序中添加NFC功能,它工作正常。但问题是我第一次无法读取/写入NFC卡。第一次,我需要使用NFC工具应用程序编写一个新标签,将“NdeFormatable”转换为“Ndef”,否则我无法读取/写入NFC卡 我用这段代码写数据: 这个问题有什么解决办法吗?

  • 问题内容: 我想使用其中包含图像。 我不想使用,因为我想将此主体直接写入文件并希望对其进行解码,所以我只想使用对内容的引用来传递给进一步的函数调用, 我尝试创建读取器的多个实例,如下所示 但是在第二次通话中它总是导致。 请帮助我如何为同一读者传递多个单独的参考? 问题答案: 被视为流。因此,您无法阅读两次。想象一下传入的TCP连接。您无法倒带进来的内容。 但是您可以使用复制流: Go Playgr

  • 问题内容: 我正在尝试在Python中多次读取某些文件的行。 我正在使用这种基本方式: 一切正常,但是如果我想在文件仍处于打开状态的情况下每行第二次进行迭代,例如: 然后它不起作用,我需要打开,然后关闭,然后再次打开我的文件以使其正常工作。 感谢您的回答! 问题答案: 使用file.seek()跳到文件中的特定位置。但是,请考虑是否真的有必要再次浏览该文件。也许有更好的选择。

  • 我在页面上有一个表,我需要从表中的特定单元格中读取值。我想把这些值写到excel文件中。问题是for loop只循环一次,并且只为Excel中的第一个单元格写入值。我试过很多不同的循环,在谷歌上搜索,但都找不到答案。请帮帮忙。下面是我要编写到Excel的代码: 这是我写入excel文件的地方 循环成功执行并从表中正确打印出值,但我需要将这些值写入Excel。似乎在excel中写入第一个值后,for

  • 问题内容: 我有以下代码: 和此web.xml(缩短了程序包并更改了名称,但外观相同) 我想在过滤器之后调用Servlet。我希望可以做到这一点,但是我总是会遇到以下错误: 问题答案: 你可能开始使用 in 使用HttpServletRequest : 你的servlet尝试调用相同的请求,这是不允许的。你需要做的是使用制作请求正文的副本,因此你可以使用多种方法读取它。