Что гарантирует, что переключение контекста не произойдет после вызова Thread.MemorryBarrier()?
Ничего такого. MemoryBarriers не препятствует переключению контекста (или атомарному выполнению вашего кода).
Что касается вашего другого вопроса, зачем нужен Барьер 4:
В примере кода из предыдущего вопроса компилятор C#, среда CLR или ЦП могут переупорядочить чтение переменной ответа перед завершенной переменной, если барьера 4 не было. то есть код, который фактически работает, может быть похож на:
Thread.MemoryBarrier(); // Barrier 3
int tmpanswer = _answer;
if (_complete)
{
Console.WriteLine (tmpanswer);
}
Барьер перед Console.WriteLine() предотвратит чтение _answer
перед чтением _completed
Но имейте в виду, что пример кода предоставляет только эту единственную гарантию относительно кода в void B() (при условии, что A() запускается только один раз )
- Если переменная _complete имеет значение true, то Console.WriteLine выведет 123, а не 0.
Таким образом, если A и B не запускаются последовательно, код не обеспечивает никакой блокировки/уведомления, так что B всегда будет печатать 123. A() и B() могут быть чередованы/прерваны в любое время при его выполнении - вы не можете контролировать кто когда бежит.
Нет никакой гарантии, что B() запустится после A(), независимо от того, в каком порядке вы запустили 2 потока. (Хотя где-то еще в коде вы можете сначала запустить A() и явно дождаться его завершения, прежде чем запускать B () конечно)
person
Lyke
schedule
31.08.2011