Подтвердить что ты не робот

Нужно ли мне блокировать объект при чтении?

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

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

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

Мои вопросы:

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

Нужно ли также блокировать объект при чтении с него?

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

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

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

Ответ 4

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

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

Ответ 5

Блокировка

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