Как уже упоминали другие авторы, у вас есть гонка данных, но если вы сравниваете это поведение, например, с программой, написанной на C с использованием pthreads, вы упускаете некоторые важные данные.Ваша проблема не только во времени, но и в самом определении языка.Поскольку примитивы параллелизма запекаются в самом языке, модель памяти языка Go (https://golang.org/ref/mem) точно описывает, когда и как происходят изменения в одной подпрограмме - представьте, что подпрограммы являются «сверхлегкими потоками пространства пользователя», и вы выиграли »не слишком далеко - гарантированно будет виден коду, выполняющемуся в другой программе.
Без каких-либо синхронизирующих действий, таких как отправка / получение канала или синхронизация. Блокировка / разблокировка Mutex, модель памяти Go говорит, что любойизменения, которые вы вносите в 'a' внутри этой процедуры, не когда-либо должны быть видны основной программе. И, поскольку компилятор знает это, он может оптимизировать практически все, что есть в вашем цикле forИли нет.
Это похоже на ситуацию, когда у вас, скажем, локальная переменная int в C установлена в 1, и, возможно, у вас есть цикл while, читающий эту переменную в цикле, ожидающий ее установкиISR до 0, но тогда ваш компилятор становится слишком умным и решает оптимизировать тест на ноль, потому что он thinks ваша переменная не может измениться внутри цикла, и вы действительно хотели бесконечный цикл, и поэтому вы должны объявить переменную как volatile
, чтобы исправить «ошибку».
Если выбудем работать в Go, (мой текущий любимый язык, FWIW), потратить время на прочтение и тщательно освоить модель памяти Go, о которой говорилось выше, и она действительно окупится в будущем.