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

And*_*ndy 25 multithreading mutex critical-section

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

  • A)多个写线程写入对象(所有运行相同的函数)
  • B)每5秒访问一次对象的读线程
  • C)访问对象的读取线程存在用户请求

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

我的问题是:

  1. 在读取对象时是否还需要锁定对象?
  2. 我是否认为如果我们只是在写作时锁定对象,那么关键部分就足够了; 但是如果我们在读取或写入时锁定对象,则需要互斥锁?

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

Mic*_*ski 16

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

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

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


小智 6

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

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

我认为如果我们在写入时只锁定对象,临界区就足够了,我的想法是否正确?但是如果我们在读取或写入时锁定对象,则需要互斥锁吗?

不,您可以对两者使用临界区,其他条件相同。互斥体在部分上添加了功能(例如,可以在多个进程中使用命名的互斥体),但我认为您在这里不需要这样的功能。


Ofi*_*fir 5

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

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