Являются ли ссылки присвоения и чтения атомарных операций? - PullRequest
14 голосов
/ 28 апреля 2011

Я нашел несколько вопросов по этой же теме, но связанных с общими переменными (значения и ссылочные типы) Принятый ответ от на этот вопрос говорит:

Раздел I, раздел 12.6.6 спецификации CLI гласит: «Соответствующий интерфейс командной строки должен гарантировать, что доступ на чтение и запись к правильно выровненным ячейкам памяти, не превышающим собственный размер слова, является атомарным, когда все обращения к записи в расположении того же размера. "

Ссылочные переменные (т.е. классы) - это указатели, равные собственному размеру слова, но у меня есть пара сомнений:

Гарантированно ли ссылки находятся в правильно выровненных ячейках памяти?

Я не понимаю последнюю часть. Что это значит? "... когда все доступы для записи в местоположение имеют одинаковый размер."

Короче говоря, гарантированно ли obj2 действителен на каждой итерации цикла в следующем коде?

class MyClass
{
    private OtherClass m_Object;

    void Thread1()
    {
        while(true)
        {
            OtherClass obj1 = new OtherClass();
            m_Object = obj1;
        }
    }

    void Thread2()
    {
        while (true)
        {
            OtherClass obj2 = m_Object;
            // Is obj2 guaranteed to be valid?
            obj2.Check();
        }
    }
}

1 Ответ

11 голосов
/ 28 апреля 2011

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

Раздел 12.6.6 спецификации CLIпродолжает:

Если явное управление макетом (см. Раздел II (Управление макетом экземпляра)) не используется для изменения поведения по умолчанию, элементы данных не превышают естественный размер слова (размерnative int) должны быть правильно выровнены.Ссылки на объекты должны обрабатываться так, как если бы они хранились в собственном размере слова.

Более подробные сведения о выравнивании и т. Д. Приведены в разделе 12.6.2 спецификации.

Обратите внимание, чтов вашем примере кода чтение в потоке 2 гарантированно будет атомарным, но оно не гарантированно фактически увидит любые изменения, сделанные потоком 1: без применения барьеров памяти или изменчивости каждый поток может использовать свое собственное представление"поля m_Object, не видя изменений, внесенных другими потоками.

Так, например, поток 1 может делать (атомарные) записи в собственном представлении m_Object, но данные толькофактически хранится в регистре или кэше процессора и никогда не помещается в основную память.Точно так же поток 2 также может делать (атомарные) чтения m_Object, но на самом деле чтение из регистра или кэша ЦП, а не из основной памяти.

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