Гарантирует ли блокировка записи новое чтение в другой ветке?(.Net, модель памяти) - PullRequest
3 голосов
/ 06 марта 2011

Скажем, у меня есть свойство, чей установщик защищен блокировкой, но без какой-либо блокировки вокруг получателя, например

private long _myField;
public long MyProperty
{
    get { return _myField; }
    set { lock(whatever) _myField = value; }
}

В дополнение к синхронизации записи (но не чтения), блокировки или, скорееMonitor.Exit должен вызвать volatile write .Давайте теперь скажем, что у нас есть два потока A и B, и происходит следующая последовательность:

  1. A читает текущее значение MyProperty.
  2. B записывает новое значение в MyProperty.
  3. A снова считывает текущее значение MyProperty.

Q: А теперь гарантированно A видит новое значение?Или наша блокировка просто гарантирует, что B своевременно записывает в основную память, а другие потоки не читают новое значение?Или же ответ может зависеть от того, работаем ли мы в .Net 2+ или в «более слабой» реализации ECMA?

Ответы [ 2 ]

3 голосов
/ 06 марта 2011

Нет, поскольку чтение не имеет явного барьера памяти, «новое» не гарантируется для просмотра нового значения.

Вы можете использовать ReaderWriterLockSlim, чтобы гарантировать, что a) записи блокируют друг друга и b) чтения всегда получают новое значение.

private readonly ReaderWriterLockSlim _myFieldLock = new ReaderWriterLockSlim();
private long _myField;
public long MyProperty
{
    get 
    {
        _myFieldLock.EnterReadLock();
        try
        {
            return _myField;
        }
        finally
        {
            _myFieldLock.ExitReadLock();
        }
    }
    set
    {
        _myFieldLock.EnterWriteLock();
        try
        {
            _myField = value;
        }
        finally
        {
            _myFieldLock.ExitWriteLock();
        }
    }
}
1 голос
/ 06 марта 2011

Если вы использовали Interlocked.Read в геттере, вы всегда должны прочитать новое значение.См. Threading в C # для получения дополнительной информации о заборах памяти

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