Является ли чтение (просто чтение из чего-то, что было инициализировано ранее) из поля всегда потокобезопасным?
Язык C# гарантирует, что операции чтения и записи будут последовательно упорядочены, когда операции чтения и записи выполняются в одном потоке в разделе 3.10:
Зависимость данных сохраняется в потоке выполнения. То есть значение каждой переменной вычисляется так, как если бы все операторы в потоке выполнялись в исходном порядке программы. Правила порядка инициализации сохраняются.
События в многопоточной многопроцессорной системе не обязательно имеют четко определенный непротиворечивый порядок во времени по отношению друг к другу. Язык C# не гарантирует последовательного порядка. Последовательность операций записи, наблюдаемая одним потоком, может наблюдаться в совершенно другом порядке при наблюдении из другого потока, если не задействована критическая точка выполнения.
Таким образом, на вопрос нельзя ответить, поскольку он содержит неопределенное слово. Можете ли вы дать точное определение того, что для вас означает «предыдущий» по отношению к событиям в многопоточной многопроцессорной системе?
Язык гарантирует, что побочные эффекты упорядочены только по отношению к критическим точкам выполнения, и даже в этом случае не дает никаких надежных гарантий, когда задействованы исключения. Опять же, цитата из раздела 3.10:
Выполнение программы C# происходит таким образом, что побочные эффекты каждого выполняемого потока сохраняются в критических точках выполнения. Побочный эффект определяется как чтение или запись изменчивого поля, запись в энергонезависимую переменную, запись во внешний ресурс и создание исключения. Критическими точками выполнения, в которых должен быть сохранен порядок этих побочных эффектов, являются ссылки на изменчивые поля, операторы блокировки и создание и завершение потока. [...] Порядок побочных эффектов сохраняется в отношении изменчивых операций чтения и записи.
Кроме того, среде выполнения не нужно оценивать часть выражения, если она может сделать вывод, что значение этого выражения не используется и что не создаются необходимые побочные эффекты (включая любые, вызванные вызовом метода или доступом к изменчивому полю). Когда выполнение программы прерывается асинхронным событием (например, исключением, созданным другим потоком), не гарантируется, что наблюдаемые побочные эффекты будут видны в исходном порядке выполнения программы.
Является ли доступ к объекту из массива или списка всегда потокобезопасным (в случае, если вы используете цикл for для перечисления)?
Под потокобезопасностью вы подразумеваете, что два потока всегда будут получать согласованные результаты при чтении из списка? Как отмечалось выше, язык C# дает очень ограниченные гарантии наблюдения результатов при чтении из переменных. Можете ли вы дать точное определение того, что для вас означает потокобезопасность в отношении энергонезависимого чтения?
Является ли перечисление всегда/когда-либо потокобезопасным?
Даже в однопоточных сценариях изменение коллекции при ее перечислении является незаконным. Это, безусловно, небезопасно в многопоточных сценариях.
Может ли запись и чтение в определенное поле привести к повреждению чтения (половина поля изменена, а половина остается неизменной)?
да. Я отсылаю вас к разделу 5.5, в котором говорится:
Чтение и запись следующих типов данных являются атомарными: bool, char, byte, sbyte, short, ushort, uint, int, float и ссылочные типы. Кроме того, операции чтения и записи типов перечисления с базовым типом из предыдущего списка также являются атомарными. Чтение и запись других типов, включая long, ulong, double и decimal, а также определяемые пользователем типы, не обязательно являются атомарными. Помимо библиотечных функций, предназначенных для этой цели, нет никакой гарантии атомарного чтения-изменения-записи, например, в случае увеличения или уменьшения.
person
Eric Lippert
schedule
26.04.2011