none
C# Будет ли атомарным изменение значения переменной значимого типа объявленной в структуре или классе? RRS feed

  • Вопрос

  • Здравствуйте!

    Вот тут прочитал, что "процессор гарантирует атомарность только если переменная, с которой осуществляется чтение или запись, правильно выровнена (aligned) в памяти." и ниже "если вы скажите CLR поместить поле типа int внутри структуры и нарушите правила выравнивания, тогда доступ к этому полю не будет атомарным, и это будет вашей проблемой." Таким образом, появляется вопрос: как узнать, что поля структуры выровнены правильно и, в конечном итоге, чтение/запись будут атомарными? Распространяется ли данное явление на класс?

    Вот сама структура:

    public struct ReadyUpload
        {
            /// <summary>
            /// Чтение и запись этого поля, как я понимаю, не будет атомарным в любом случае?
            /// </summary>
            public bool? filesRead;
            public bool readAtLeastOneFile;
            public bool listsReceived;
            public bool excelIsRunning;
        }

    Заранее спасибо!


    13 марта 2015 г. 11:30

Ответы

  • Очень просто: если нет атрибута [StructLayoutt(...)] то поля всегда правильно выровнены.

    Если есть то надо смотреть какой тип выравнивания задан и какие именно атрибуты присвоены конкретному полю. 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    • Помечено в качестве ответа nik_w 15 марта 2015 г. 12:18
    14 марта 2015 г. 2:00
    Модератор

Все ответы

  • Зависит от типа значимой переменной. Атомарность filesRead в данном случае не гарантируется, так как это тип допускающий null. А вот с остальными полями всё нормально. Статья которую вы привели немного говорит о другом, вам следует прочитать первую часть.

    Сделаем содержимое сообщества лучше, вместе!

    13 марта 2015 г. 20:01
    Модератор
  • Процессор исполняет машинные инструкции, а не IL-код. О какой атомарности может идти речь, если даже элементарная неуправляемая операция инкремента на C++ разбивается на несколько машинных команд. Синхронизация и еще раз синхронизация, если не хотите лишних проблем.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    13 марта 2015 г. 21:49
  • Очень просто: если нет атрибута [StructLayoutt(...)] то поля всегда правильно выровнены.

    Если есть то надо смотреть какой тип выравнивания задан и какие именно атрибуты присвоены конкретному полю. 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    • Помечено в качестве ответа nik_w 15 марта 2015 г. 12:18
    14 марта 2015 г. 2:00
    Модератор
  • Всем спасибо за ответы. Решил убрать структуру, вместо неё создал статический класс. Получилось вот так:

    public static class ReadyUpload
        {
            public enum ReadState { Сompleted, NotCompleted, NotStarted }
            public static ReadState filesRead;
            public static bool readAtLeastOneFile;
            public static bool listsReceived;
            public static bool excelIsRunning;
    
            public static bool CheckReadyUpload()
            {
            }
        }
    Нужно ли в данном случае синхронизировать доступ? Я предполагаю, что не нужно, кроме поля filesRead, которое имеет тип перечисления.
    14 марта 2015 г. 12:44
  • Зависит от того что вы делайте с данным классом.

    Если рассматривать все с точки зрения изменения отдельных полей то все они будут изменяться одной командой процессора.

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


    This posting is provided "AS IS" with no warranties, and confers no rights.

    14 марта 2015 г. 17:56
    Модератор
  • Поля класса будут меняться в разных задачах, а их значения будут считываться только в методе CheckReadyUpload(). При этом, во время работы метода, изменение значения некоторых полей ещё возможно.

    На RSDN пишут, что статические поля не являются потокобезопасными (пример, со статическим полем done).

    Так всё-таки нужно ли синхронизировать доступ или нет? Я бы уж лучше синхронизировал, используя тот же Monitor, например.

    15 марта 2015 г. 9:00
  • Я Вам уже все сказал, или что-то не понятно? Конечно, синхронизировать. Достаточно языковой конструкции C# lock, которая реализована как раз через Monitor.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Предложено в качестве ответа YatajgaEditor 15 марта 2015 г. 16:24
    • Отменено предложение в качестве ответа nik_w 15 марта 2015 г. 18:18
    15 марта 2015 г. 10:32