C++ 我可以从不同线程读取内存缓冲区而不使用任何锁吗?

C++ 我可以从不同线程读取内存缓冲区而不使用任何锁吗?,c++,multithreading,locking,C++,Multithreading,Locking,假设我有一个内存缓冲区,不同的线程想要读取它(所以不需要更改),我需要一个锁来防止并发读取吗 我知道,对于写作,我们应该确保只有一个线程可以向其写入,但读取时的情况如何 要澄清的是,缓冲区是一个表,几个线程可以读取并使用它,但它是一个常量表,在程序启动时和任何线程启动之前从磁盘读取 所以事情是这样发生的: 节目开始 程序从磁盘读取表值 程序创建线程并将数据传递给它们 不同的线程通过读取此表和其他一些数据来处理数据,并生成一些数据,但没有线程更改此表 节目结束 假设我有一个内存缓冲区,不同的线程想

假设我有一个内存缓冲区,不同的线程想要读取它(所以不需要更改),我需要一个锁来防止并发读取吗

我知道,对于写作,我们应该确保只有一个线程可以向其写入,但读取时的情况如何

要澄清的是,缓冲区是一个表,几个线程可以读取并使用它,但它是一个常量表,在程序启动时和任何线程启动之前从磁盘读取

所以事情是这样发生的:

  • 节目开始
  • 程序从磁盘读取表值
  • 程序创建线程并将数据传递给它们
  • 不同的线程通过读取此表和其他一些数据来处理数据,并生成一些数据,但没有线程更改此表
  • 节目结束
  • 假设我有一个内存缓冲区,不同的线程想要读取它(所以不需要更改),我需要一个锁来防止并发读取吗

    只要在填充缓冲区后进行读取,那么不需要任何同步。只要您只读取同一对象,就不需要同步

    只有当一个或多个写入程序尝试修改对象,或者一个或多个写入程序尝试修改对象,而一个或多个读取程序尝试读取其值时,才需要同步

    我需要锁来防止并发读取吗

    没有


    但是,如果在线程之前进行了写操作,那么,根据您所在的机器的不同,稍后的读取可能会返回不同的值。

    如果多个线程正在读取缓冲区,而没有线程写入缓冲区,那么并发读取通常不是问题。例如,如果缓冲区是在创建线程之前填充的,并且从未更改,那么读取可以是并发的,而不需要锁


    如果任何线程正在修改缓冲区,那么读写都需要一个锁。这对于防止写操作干扰读操作和写操作是必要的-例如,防止在部分写入时读取缓冲区。

    必须有东西写入该缓冲区,否则它将不包含任何值得读取的内容。如果在创建线程之前已完全写入内存缓冲区,那么就不需要锁/内存障碍了;数据是静态的。那么不,你不需要锁。但是,如果数据可能会发生变化,那么您确实需要锁。如果没有缓存一致性,写操作可能不会被多核处理器中的其他核看到。这怎么可能呢?@LWimsey:非缓存一致性体系结构。请参阅维基百科-这是相当大的开销。在一些多核处理器(更不用说多插槽)上,一些缓存级别没有保持一致;因此,最近一个核心的写可能不会一直传播到实际RAM,然后使其他内核的低级缓存失效,然后从那个地址读取。有趣的观点,但是它违反了C++标准的要求,即线程创建之前线程本身可以看到内存操作的顺序。(N47 13,PAR.33.3.2.2-6[线程构造函数])在一个没有缓存一致性的平台上,不连贯的内存视图是可能的(负载返回过时的值),但不是在同步之后。@ LWMSE:我实际上是在思考线程在写入期间已经存在的时候。