Нужно ли блокировать объект при чтении с него? - PullRequest
23 голосов
/ 31 января 2010

Я пишу программу, в которой есть объект, совместно используемый несколькими потоками:

  • A) Несколько потоков записи записывают в объект (все работают одинаково функция)
  • B) Поток чтения, который обращается к объекту каждые 5 секунд
  • C) Поток чтения, который обращается к объекту, там есть запрос пользователя

Очевидно, что необходимо заблокировать объект при записи в него, поскольку мы не хотим, чтобы несколько потоков писали в объект одновременно.

Мои вопросы:

  1. Также необходимо заблокировать объект при чтении с него?
  2. Правильно ли я считаю, что если мы просто блокируем объект при записи, достаточно критической секции; но если мы блокируем объект при чтении или записи, необходим мьютекс?

Я задаю этот вопрос, потому что в Microsoft Office два экземпляра Word не могут получить доступ к документу в режиме чтения / записи; но когда документ открывается в режиме чтения / записи, можно открыть другой экземпляр Word для доступа к документу в режиме только для чтения. Будет ли применяться та же логика в потоке?

Ответы [ 5 ]

14 голосов
/ 31 января 2010

Как уже писал Офир - если вы попытаетесь прочитать данные из объекта, который модифицирует какой-то другой поток, - вы можете получить данные в некотором несовместимом состоянии.

Но - если вы уверены, что объект не изменяется, вы, конечно, можете прочитать его из нескольких потоков. В общем, вопрос, который вы задаете, - это более или менее проблема читателей-писателей - см. http://en.wikipedia.org/wiki/Readers-writers_problem

Наконец, критический раздел является абстрактным термином и может быть реализован с использованием мьютекса или монитора. Синтаксический сахар для критической секции в java или C # (синхронизирован, блокировка) использует монитор под крышками.

4 голосов
/ 31 января 2010

Это необходимо, потому что в противном случае (если операции не являются атомарными) вы можете читать промежуточное состояние.

Вы можете разрешить одновременное использование нескольких считывателей, что требует (немного) более сложного вида блокировки.

3 голосов
/ 31 января 2010

Также необходимо заблокировать объект при чтении с него?

Если что-то еще может написать в это же время - да. Если только может произойти другое чтение - нет. В ваших обстоятельствах я бы сказал - да.

Правильно ли я считаю, что если мы просто заблокируем объект при записи, достаточно критической секции; но если мы заблокировать объект при чтении или пишешь, мьютекс нужен?

Нет, вы можете использовать критическую секцию для обоих при прочих равных условиях. Мьютексы добавили функции над секциями (например, именованные мьютексы можно использовать в нескольких процессах), но я не думаю, что вам здесь нужны такие функции.

2 голосов
/ 31 января 2010
  1. зависит от того, как вы его используете и читаете. если ваше чтение является атомарным (т.е. не будет прервано записью) и поток чтения не зависит от потоков записи, то вы, возможно, сможете пропустить блокировку чтения. Но если ваша операция чтения занимает некоторое время и требует взаимодействия с тяжелыми объектами, вам следует заблокировать ее для чтения.

  2. если ваше чтение не займет очень много времени (т.е. не задержит потоки записи слишком долго), критической секции должно быть достаточно.

0 голосов
/ 02 августа 2014
Блокировка

необходима только тогда, когда два процесса могут изменять одни и те же элементы таблицы базы данных. когда вы хотите прочитать данные, это всегда безопасно. Вы читаете данные согласованной базы данных. процесс, изменяющий данные, имеет теневую версию, которая является последовательной и переопределяет текущие данные при сохранении. но если вы запускаете процесс чтения, который зависит от критического значения из элементов базы данных, вам следует искать блокировки, которые указывают, что эти значения могут быть изменены. поэтому ваше чтение задерживается до тех пор, пока блокировка не исчезнет.

...