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

时间:2010-01-31 12:42:20

标签: multithreading mutex critical-section

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

  • A)多个写入线程写入对象(全部运行相同 功能)
  • B)每隔5秒访问一次对象的读取线程
  • C)访问该对象的读取线程有用户请求

显然有必要在写入对象时锁定对象,因为我们不希望多个线程同时写入对象。

我的问题是:

  1. 在阅读时还需要锁定对象吗?
  2. 我认为如果我们只是在写作时锁定对象,那么关键部分就足够了;但是如果我们在读或写时锁定对象,则需要互斥锁吗?
  3. 我问的是这个问题,因为在Microsoft Office中,两个Word实例无法以读/写访问模式访问文档;但是当文档以读/写模式打开时,可以打开另一个Word实例以只读模式访问文档。线程会采用相同的逻辑吗?

5 个答案:

答案 0 :(得分:14)

正如Ofir已经写过的 - 如果你试图从一个其他线程正在修改的对象中读取数据 - 你可能会得到一些不一致状态的数据。

但是 - 如果您确定该对象未被修改,您当然可以从多个线程中读取它。一般来说,您提出的问题或多或少是读者 - 作家的问题 - 请参阅http://en.wikipedia.org/wiki/Readers-writers_problem

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

答案 1 :(得分:4)

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

您可能希望同时允许多个读取器,这需要一个(位)更复杂的锁定。

答案 2 :(得分:3)

  

在阅读对象时是否还需要锁定对象?

如果其他东西可以同时写入 - 是的。如果只发生另一次读取 - 没有。在你的情况下,我会说 - 是的。

  

我认为如果我们只是在写作时锁定对象,我是正确的   关键部分就足够了;但如果我们   在阅读时锁定对象或   写作,互斥是必要的吗?

不,你可以使用两个关键部分,其他条件相同。互斥体在部分上添加了功能(例如,可以在多个进程中使用命名的互斥锁),但我认为您不需要这些功能。

答案 3 :(得分:1)

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

  2. 如果你的阅读时间不长(即不会延迟写线程太长),那么关键部分应该足够了。

答案 4 :(得分:0)

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