Я прочитал довольно много сообщений на эту тему, и я, наконец, понял, как работает ключевое слово 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++
не является атомарной операцией, но если один поток выполняет все приращения, а другой просто хочет прочитать его, чтобы увидеть, достигает ли он определенного порога, мы в порядке, верно?
Изменить: Я, конечно, я нашел другой аналогичный вопрос с подробными ответами после факт.