Когда записи/чтения влияют на оперативную память?

Проблема проанализировать HTML состоит в том, что это не точная наука. Если бы это был XHTML, который Вы анализировали, то вещи были бы намного легче (поскольку Вы упоминаете, что могли использовать общий синтаксический анализатор XML). Поскольку HTML является не обязательно правильно построенным XML, Вы войдете в большое количество проблем, пытающихся проанализировать его. Это почти должно быть сделано на основе сайта сайтом.

5
задан Peter Mortensen 14 November 2009 в 14:01
поделиться

4 ответа

Volatile и Interlocked уже упоминались, вы запрашивали примитивы, одно дополнение к списку - использовать Thread.MemoryBarrier () перед записью или чтением. Это гарантирует отсутствие переупорядочивания операций записи и чтения в память.

Это делается «вручную», что lock , Interlocked и volatile может делать автоматически большую часть времени. Вы можете использовать это как полную замену любому другому методу, но это, пожалуй, самый трудный путь, и так говорится в MSDN:

«Трудно создавать правильные многопоточные программы, используя MemoryBarrier. Для большинства целей Оператор блокировки C #, Visual Basic Оператор SyncLock и методы класс Monitor обеспечивает более простой и менее подверженные ошибкам способы синхронизации доступ к памяти. Мы рекомендуем вам используйте их вместо MemoryBarrier. "

Как использовать MemoryBarrier

Прекрасным примером являются реализации VolatileRead и VolatileWrite , которые внутренне используют MemoryBarrier . Основное правило Практический пример: когда вы читаете переменную, установите барьер памяти после чтения. Когда вы записываете значение, барьер памяти должен стоять до записи.

Если вы сомневаетесь, что это менее эффективно, чем блокировка , примите во внимание, что блокировка - это не что иное, как «полное ограждение», поскольку она устанавливает барьер памяти до и после блока кода (игнорируя Monitor для Этот принцип хорошо объяснен в отличной окончательной статье о потоках, блокировках, барьеры энергозависимости и памяти Альбахари .

Из отражателя:

public static void VolatileWrite(ref byte address, byte value)
{
    MemoryBarrier();
    address = value;
}

public static byte VolatileRead(ref byte address)
{
    byte num = address;
    MemoryBarrier();
    return num;
}
3
ответ дан 18 December 2019 в 09:08
поделиться

Если вы хотите, чтобы он был написан быстро и по порядку, пометьте его как volatile или (с большим трудом) используйте Thread.VolatileRead / Thread.VolatileWrite (вариант не очень привлекательный, и его легко пропустить, что делает его бесполезным)

volatile int m_foo;

В противном случае у вас практически нет никаких гарантий (как только вы говорите в нескольких потоках).

Вы также можете посмотреть на блокировку ( Монитор ) или Блокировка , которые достигли бы того же эффекта , пока то же [ Подход 1129269] используется из любого доступа (т.е. вся блокировка , или все заблокировано и т. Д.).

11
ответ дан 18 December 2019 в 09:08
поделиться

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

Следовательно, вам нужно либо пометить переменную как изменчивую. Это создаст реальность «Произойдет до» между чтением и записью.

2
ответ дан 18 December 2019 в 09:08
поделиться

Это не проблема кэша процессора. Записи обычно являются сквозными (записи идут как в кеш, так и в основную память), и все чтения будут иметь доступ к кешу. Но на подходе много других кешей (язык программирования, библиотеки, операционная система, буферы ввода-вывода и т. Д.). Компилятор также может сохранить переменную в регистре процессора и никогда не записывать ее в основную память (для этого предназначен volatile-оператор, избегайте сохранения значения в регистре, когда это может быть ввод-вывод, отображаемый в память).

Если у вас есть несколько процессов или несколько потоков и синхронизация является проблемой, вы должны сделать это явно, в зависимости от варианта использования есть много способов сделать это.

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

2
ответ дан 18 December 2019 в 09:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: