Подтвердить что ты не робот

Does Go поддерживает изменчивые/энергонезависимые переменные?

Я новичок в языке, так что несите меня.

Мне любопытно, как GO обрабатывает хранилища данных, доступные для потоков, в том смысле, что нелокальные переменные также могут быть энергонезависимыми, например, в Java.

GO имеет концепцию канала, которая по своей природе - межпоточная связь означает, что она обходит кеш процессора и напрямую читает/записывает кучу.

Кроме того, не нашли ссылки на volatile в документации go lang.

4b9b3361

Ответ 1

TL; DR: Go не имеет ключевого слова, чтобы сделать переменную безопасной для нескольких goroutines для записи/чтения. Для этого используйте пакет sync/atomic. Или еще лучше Не обмениваться данными путем обмена памятью; вместо этого, обмениваться памятью, обмениваясь.


Два ответа для два значения volatile volatile Ven diagram

.NET/Java concurrency

Некоторые выдержки из Go Memory Model.

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

Один из примеров из Некорректная синхронизация - пример оживленного ожидания по значению.

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

Действительно, этот код (play.golang.org/p/K8ndH7DUzq) никогда не выходит.

Нестандартная память C/С++

Модель памяти p > Go не обеспечивает способ обращения к нестандартной памяти. Если у вас есть необработанный доступ к шине ввода-вывода устройства, вам нужно использовать сборку или C, чтобы безопасно записывать значения в ячейки памяти. Мне только нужно было сделать это в драйвере устройства, что обычно не позволяет использовать Go.

Ответ 2

Простой ответ заключается в том, что volatile не поддерживается текущей спецификацией Go, периодом.

Если у вас есть один из вариантов использования, где требуется volatile, например, доступ к атомной памяти на низкоуровневом уровне, который не поддерживается существующим пакеты в стандартной библиотеке или небуферизованный доступ к аппаратной карте памяти, вам нужно будет связать в файле C или сборки.

Обратите внимание, что если вы используете C или сборку, как понимается в компиляторе GC, для этого вам даже не нужен cgo, поскольку компиляторы [568] c C/asm также могут обрабатывать его.

Вы можете найти примеры этого в исходном коде Go. Например:

Grep для многих других экземпляров.

Как работает доступ к памяти в Go, посмотрите Модель памяти Go.

Ответ 3

Нет, go не поддерживает volatile или регистр.

Для получения дополнительной информации см. этот пост. Это также отмечено в Go for С++ Programmers guide.

Ответ 4

Документация Go Memory Model объясняет, почему концепция "volatile" не имеет приложения в Go.

Свободно: среди прочего, goroutines могут свободно хранить локальные изменения goroutine в кешках в регистрах, чтобы эти изменения не наблюдались другими гортанами. Чтобы "сбросить" эти изменения в памяти, необходимо выполнить синхронизацию. Либо используя блокировки, либо путем передачи (отправки или получения канала).