Оператор + = не является атомарным, то есть сначала он читает, затем записывает новое значение. Между тем, между чтением и записью поток A может переключиться на другой B, фактически без записи значения ... тогда другой поток B не увидит новое значение, поскольку оно не было назначено другим потоком A ... и при возврате к потоку A он отбросит всю работу потока B.

жный дубликат:
Синхронизация потоков. Как именно блокировка делает доступ к памяти «правильным»?

Этот вопрос вдохновленэтот.

Мы получили следующий тестовый класс

class Test
{
    private static object ms_Lock=new object();
    private static int ms_Sum = 0;

    public static void Main ()
    {
        Parallel.Invoke(HalfJob, HalfJob);
        Console.WriteLine(ms_Sum);
        Console.ReadLine();
    }

    private static void HalfJob()
    {
        for (int i = 0; i < 50000000; i++) {
            lock(ms_Lock) { }// empty lock

            ms_Sum += 1;
        }
    }
}

Фактический результат очень близок к ожидаемому значению 100 000 000 (50 000 000 x 2, так как 2 цикла работают одновременно), с разницей в 600–200 (ошибка на моей машине составляет около 0,0004%, что очень мало). Никакой другой способ синхронизации не может обеспечить такой способ приближения (это либо гораздо большая ошибка%, либо его 100% правильность)

В настоящее время мы понимаем, что такой уровень точности обусловлен тем, что программа выполняется следующим образом:

Время идет слева направо, и 2 потока представлены двумя рядами.

где

черный ящик представляет процесс приобретения, удержания и выпуска

Блокировка плюс представляет операцию сложения (схема представляет масштаб на моем ПК, блокировка занимает примерно в 20 раз больше, чем добавить)

белый ящик представляет период, который состоит из попытки получить блокировку и дальнейшего ожидания ее появления

Также блокировка обеспечивает полную память забора.

Таким образом, теперь возникает вопрос: если вышеуказанная схема представляет собой то, что происходит, что является причиной такой большой ошибки (теперь ее схема с большой причиной выглядит как очень сильная схема синхронизации)? Мы могли бы понять разницу между 1-10 на границах, но это явно не единственная причина ошибки? Мы не можем видеть, когда запись в ms_Sum может происходить одновременно, чтобы вызвать ошибку.

РЕДАКТИРОВАТЬ: многим нравится делать быстрые выводы. Я знаю, что такое синхронизация, и что приведенная выше конструкция не является реальным или близким к хорошему способу синхронизации потоков, если нам нужен правильный результат. Имейте некоторую веру в постер или возможно прочитайте связанный ответ сначала. Мне не нужен способ синхронизации 2 потоков для параллельного выполнения дополнений, я исследую этот экстравагантный и все же эффективный по сравнению сЛюбые возможно иприближенный альтернатива, конструкция синхронизации (она синхронизирует до некоторой степени, поэтому еене бессмысленно вроде бы предложил)

Ответы на вопрос(5)

Ваш ответ на вопрос