Нужно ли блокировать объект при чтении с него?
Я пишу программу, в которой есть объект, разделяемый несколькими потоками:
- A) несколько потоков записи записывают в объект (все работают одинаково функция)
- B) поток чтения, который обращается к объекту каждые 5 секунд
- C) поток чтения, который обращается к объекту, есть запрос пользователя
очевидно, необходимо заблокировать объект при записи на него, так как мы не хотим, чтобы несколько потоков записывались на объект одновременно.
мои вопросы:
- также необходимо заблокировать объект при чтении с него?
Я задаю этот вопрос, потому что в Microsoft Office невозможно для двух экземпляров Word получить доступ к документу в режиме чтения / записи режим доступа; но в то время как документ открывается в режиме чтения/записи, можно открыть другой экземпляр Word для доступа к документу в режиме только для чтения. Применима ли та же логика к потоковой передаче?
5 ответов
Как уже писал Ofir - если вы попытаетесь прочитать данные из объекта, который модифицирует какой - то другой поток, вы можете получить данные в некотором несогласованном состоянии.
но-если вы уверены, что объект не изменяется, вы можете, конечно, прочитать его из нескольких потоков. В общем, вопрос, который вы задаете, - это более или менее проблема читателей-писателей-см. http://en.wikipedia.org/wiki/Readers-writers_problem
наконец-критический раздел является абстрактным термин и может быть реализован с помощью мьютекса или монитора. Сахар синтаксиса для критического раздела в java или C# (synchronized, lock) использует монитор под обложками.
Это необходимо, потому что в противном случае (если операции являются атомарными) вы можете читать промежуточное состояние.
вы можете позволить нескольким читателям одновременно, что требует (немного) более сложного вида блокировки.
также необходимо заблокировать объект при чтении с него?
если что - то еще может написать ему одновременно-да. Если бы только могло произойти еще одно чтение - нет. В ваших обстоятельствах, я бы сказал - Да.
правильно ли я думаю, что если мы просто заблокируем объект при записи, a критический раздел достаточно; но если мы заблокировать объект при чтении или пишешь, мьютекс нужен?
нет, вы можете использовать критический Раздел для обоих, при прочих равных условиях. Мьютексы добавили функции над разделами (например, именованные мьютексы могут использоваться из нескольких процессов), но я не думаю, что вам нужны такие функции здесь.
зависит от того, как вы используете и прочитать его. если ваше чтение атомарно (i.e, не будет прерываться записью), и поток чтения не имеет зависимости от потоков записи, тогда вы, возможно, сможете пропустить блокировку чтения. Но если ваша операция "чтение" занимает некоторое время и требует тяжелого взаимодействия с объектом, вы должны заблокировать ее для чтения.
Если ваше чтение не занимает очень много времени (т. е. не задерживает потоки записи слишком долго), критический раздел должен быть достаточно.
замок нужен только тогда, когда два процесса могут изменять одни и те же элементы таблицы базы данных. когда вы хотите читать данные, это всегда безопасно. Вы читаете данные согласованной базы данных. процесс изменения данных имеет теневую версию, которая является согласованной и переопределяет текущие данные при их сохранении. но если вы используете процесс чтения, который зависит от критического значения из элементов базы данных, вы должны искать блокировки, которые указывают, что эти значения могут быть изменены. так что ... чтение откладывается до тех пор, пока замок не исчезнет.