Состояние гонки со статическим классом? - PullRequest
5 голосов
/ 20 марта 2012

Допустим, у меня есть статический класс со статическим методом.

Несколько потоков могут вызывать этот статический метод одновременно.

Существует ли вероятность возникновения состояния гонки при следующих обстоятельствах:

a - if the method depends only on local variables
b - if the method depends on local variables and member fields

Ответы [ 3 ]

22 голосов
/ 20 марта 2012

Допустим, у меня есть статический класс со статическим методом. Несколько потоков могут вызывать этот статический метод одновременно.

OK.

Есть ли вероятность расы при следующих обстоятельствах: а - если метод зависит только от локальных переменных

Да, есть потенциальные условия гонки.

b - если метод зависит от локальных переменных и полей-членов

Да, есть потенциальные условия гонки.

Ответы на (a) и (b) являются следствием более общего правила, а именно: всегда потенциал для условий гонки любой раз, когда вы позвоните любой метод из нескольких потоков. Например, эта программа блокируется:

class MyClass
{
  static MyClass() 
  {
    // Let's run the initialization on another thread!
    var thread = new System.Threading.Thread(Initialize);
    thread.Start();
    thread.Join();
  }

  static void Initialize() 
  { }

  static void Main() 
  { }
}

У него нет полей, два метода, которые абсолютно ничего не делают, и одна локальная переменная, доступ к которой возможен только в одном потоке. И тем не менее, это сразу и последовательно тупики. (Вы понимаете, почему? Подробнее об этой программе см. http://ericlippert.com/2013/01/31/the-no-lock-deadlock/.)

Похоже, вы ищете гарантию, что ваша программа является поточно-ориентированной, если ваши статические методы не обращаются к полям. Такой гарантии нет. Ваша программа является поточно-безопасной тогда и только тогда, когда вы пишете ее как поточно-безопасную.

5 голосов
/ 20 марта 2012

Во-первых, метод - это просто кусок кода, находящийся по адресу. Каждый поток, вызывающий метод, будет иметь копию этого метода и его локальных переменных в своем собственном стеке. Таким образом, в случае a, при условии, что нет других защелок, должно быть поточно-ориентированным .

Случай b зависит от множества факторов:

  • действительно ли вы обращаетесь к этим переменным-членам?
  • как вы к ним обращаетесь: только чтение, чтение + запись и т. Д.
  • какие переменные-члены: структуры данных, отдельные значения.
  • есть ли у вас синхронизация?
  • и т.д.

Как правило, если вы имеете доступ к членам класса, это не следует считать поточно-ориентированным .

3 голосов
/ 20 марта 2012

A - Нет. Условия гонки возникают, только когда статические методы пытаются получить доступ к общему ресурсу.Локальная переменная будет уникальной для каждого потока, вызывающего метод.

B - Да.Эти статические члены будут общими для всех потоков, вызывающих этот метод.

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