Multithreading 读取对象时是否需要锁定对象?

Multithreading 读取对象时是否需要锁定对象?,multithreading,mutex,critical-section,Multithreading,Mutex,Critical Section,我正在编写一个程序,其中有一个对象由多个线程共享: A) 多个写入线程写入对象(所有线程都运行相同的 功能) B) 每5秒访问对象的读取线程 C) 当用户请求时访问对象的读取线程 显然,在写入对象时必须锁定该对象,因为我们不希望多个线程同时写入该对象 我的问题是: 读取对象时是否也需要锁定对象 我是否正确地认为,如果我们在写作时只锁定对象,一个关键部分就足够了;但是如果我们在读写时锁定了对象,那么互斥锁是必要的吗 我问这个问题是因为在Microsoft Office中,Word的两个实例不可

我正在编写一个程序,其中有一个对象由多个线程共享:

  • A) 多个写入线程写入对象(所有线程都运行相同的 功能)
  • B) 每5秒访问对象的读取线程
  • C) 当用户请求时访问对象的读取线程
显然,在写入对象时必须锁定该对象,因为我们不希望多个线程同时写入该对象

我的问题是:

  • 读取对象时是否也需要锁定对象
  • 我是否正确地认为,如果我们在写作时只锁定对象,一个关键部分就足够了;但是如果我们在读写时锁定了对象,那么互斥锁是必要的吗

  • 我问这个问题是因为在Microsoft Office中,Word的两个实例不可能以读/写访问模式访问文档;但是,当文档以读/写模式打开时,可以打开另一个Word实例以只读模式访问文档。同样的逻辑是否适用于线程?

    这是必要的,因为否则(除非操作是原子的),您可能正在读取中间状态

    您可能希望同时允许多个读卡器,这需要一种(稍微)更复杂的锁

    读取对象时是否也需要锁定对象

    如果有别的东西可以同时给它写信-是的。如果能再读一次就好了-不。在你的情况下,我会说-是的

    我认为如果我们在写作时锁定对象,那么 临界截面足够;但是如果我们 读取或删除时锁定对象 写的时候,互斥是必要的吗

    不,在其他条件相同的情况下,两种方法都可以使用临界截面。互斥体在部分上添加了一些特性(例如,命名互斥体可以从多个进程中使用),但我认为这里不需要这些特性

  • 取决于你如何使用和阅读它。如果您的读取是原子的(即,不会被写入中断),并且读取线程与写入线程没有依赖关系,那么您可能可以跳过读取锁定。但如果您的“读取”操作需要一些时间,并且需要重对象交互,那么您应该将其锁定以进行读取

  • 如果您的读取不会花费很长的时间(即不会将写入线程延迟太长),关键部分应该足够了


  • 正如Ofir所写的——如果您试图从某个其他线程正在修改的对象中读取数据——您可能会在某种不一致的状态下获取数据

    但是-如果您确定对象没有被修改,您当然可以从多个线程读取它。一般来说,你所问的问题或多或少是读者-作者问题-参见


    最后-关键部分是一个抽象术语,可以使用互斥锁或监视器来实现。java或C#(synchronized,lock)中关键部分的语法sugar使用隐藏的监视器。

    只有当两个进程可以更改相同的数据库表元素时,才需要锁定。
    当您想要读取数据时,它总是安全的。您可以读取一致数据库的数据。更改数据的过程具有一致的卷影版本,并且在保存数据时将覆盖当前数据。但是,如果您正在运行一个依赖于数据库元素的临界值的读取过程,那么您应该查找指示这些值可能被更改的锁。所以你的读数会被延迟,直到锁消失

    看看关系数据库是如何做到这一点的是很有用的,它们是共享数据访问的大师。谢谢。我现在意识到,关键部分可以用于不同的子例程,只要这些子例程属于同一个进程。写操作是原子操作,但非常感谢您的回答。