Использование volatile для односторонней связи между потоками в .NET - PullRequest
6 голосов
/ 03 ноября 2011

Я прочитал довольно много сообщений на эту тему, и я, наконец, понял, как работает ключевое слово volatile в C #.Тем не менее, я хотел спросить здесь, чтобы убедиться, что я правильно понимаю концепции.Рассмотрим следующий код:

class ThreadWrapper
{
  public bool Enabled { get; set; }

  private void ThreadMethod()
  {
    while (Enabled) { // ... Do work }
  }
}

Из того, что я понимаю, если бы другой поток должен был установить Enabled=false, исходный поток мог бы на самом деле не увидеть это изменение сразу (или, возможно, когда-либо?).Чтобы убедиться, что компилятор не оптимизирует доступ к свойству Enabled и полагается на кэшированные значения, изменение кода следующим образом должно исправить ситуацию.

  public bool Enabled { get {return mEnabled;} set {mEnabled=value;} }
  private volatile bool mEnabled;

Теперь, когда значение Enabled читается, оно гарантированнополучить его самое последнее значение, правильно?Если это так, я должен иметь возможность использовать его как простой сигнал или флаг (как у меня выше).

В качестве другого примера рассмотрим следующее:

class C
{
  private volatile int i;
  private volatile bool enabledA;
  private volatile bool enabledB;

  void ThreadA()
  {
    i = 0; // Reset counter
    while (enabledA)
    {
      // .. Do some other repeated work
      if (i > 100)
      {
        // .. Handle threshold case
      }
    }
  }

  void ThreadB()
  {
    while (enabledB)
    {
      // .. Do work
      if (condition) // Some condition occurs that we want to count
      {
        i++;
      }
    }
  }
}

Для простого взаимодействияпоток сообщений, как это, volatile здесь удовлетворительно?Я понимаю, что i++ не является атомарной операцией, но если один поток выполняет все приращения, а другой просто хочет прочитать его, чтобы увидеть, достигает ли он определенного порога, мы в порядке, верно?

Изменить: Я, конечно, я нашел другой аналогичный вопрос с подробными ответами после факт.

Ответы [ 2 ]

5 голосов
/ 03 ноября 2011

Я верю, что вы правы.

В статье MSDN по ключевому слову volatile в этом примере используется та же самая техника.

3 голосов
/ 03 ноября 2011

Да, это должно быть безопасно и является одним из предполагаемых применений ключевого слова volatile.Обратите внимание, однако, что вам не следует зацикливать просто для проверки условия;если вы хотите просто подождать, пока он изменится, используйте правильный примитив синхронизации, чтобы не тратить процессорное время.Также обратите внимание, что этот метод работает только потому, что у вас есть только один поток записи;если несколько потоков пытаются увеличить счетчик, вы можете потерять счетчики (потому что чтение-изменение-запись не является атомарным).

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