Стоит ли блокировать ресурсы при чтении значений? - PullRequest
4 голосов
/ 10 января 2009

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

например у меня есть объект Queue . Должен ли я просто заблокировать его при выполнении Enqueue и Dequeue или я должен также заблокировать его при проверке значений, таких как Count?

Ответы [ 4 ]

3 голосов
/ 10 января 2009

Из MSDN:

Очередь <(Of <(T>)>) может поддерживать несколько читателей одновременно, как долго так как коллекция не изменена. Несмотря на это, перечисляя через коллекция изначально не потокобезопасная процедура. Гарантировать поток безопасности при перечислении, вы может заблокировать коллекцию во время полное перечисление. Чтобы позволить Коллекция будет доступна нескольким темы для чтения и письма, вы должен реализовать свой собственный синхронизации.

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

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

if(queue.Count > 0)
    queue.Dequeue();
2 голосов
/ 10 января 2009

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

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

1 голос
/ 10 января 2009

Если вы не заблокируете его, вы можете получить более старое значение. Условие состязания может возникнуть так, что операция записи выполняется с изменением числа, но вы получите значение до изменения. Например, если в очереди есть только один элемент, и поток вызывает dequeue, другой поток может считать счетчик, найти его еще 1 и снова вызвать dequeue. Второй вызов не будет выполнен, пока не будет предоставлена ​​блокировка, но в это время очередь фактически будет пустой.

0 голосов
/ 10 января 2009

CLR гарантирует атомарное чтение для значений вплоть до ширины процессора. Так что если вы работаете на 32-битной версии, чтение int s будет атомарным. Если вы работаете на 64-битной машине, чтение long s будет атомарным. Ergo, если Count является Int32, нет необходимости блокировать.

Это сообщение относится к вашему вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...