#go #memory #concurrency
#Вперед #память #параллелизм
Вопрос:
Ниже приведен пример из https://golang.org/ref/mem:
var c = make(chan int)
var a string
func f() {
a = "hello, world"
<-c
}
func main() {
go f()
c <- 0
print(a)
}
также гарантированно выводится «привет, мир». Запись в a происходит до получения на c, что происходит до завершения соответствующей отправки на c, которая происходит до печати.
Если бы канал был буферизован (например, c = make(chan int, 1)), то программа не могла бы гарантированно напечатать «привет, мир». (Это может привести к печати пустой строки, сбою или сделать что-то еще.)
Я понимаю это It might print the empty string
, но не для crash
или do something else
когда это crash
произойдет? И когда это произойдет do something else
?
Комментарии:
1. Поведение не определено. Не пытайтесь найти в этом логику. Читайте: Безобидные скачки данных: что может пойти не так? А если нет, то enogh: скачки данных Golang нарушают безопасность памяти
Ответ №1:
Строка в Go — это фрагмент байтов, доступный только для чтения. Срез состоит из длины указателя. Давайте предположим, что сначала мы устанавливаем length в большое значение, а затем меняем указатель. Другая процедура go может сначала прочитать новую длину и старый указатель. Затем он пытается прочитать конец предыдущей строки. Он либо считывает какой-то мусор, либо останавливается операционной системой и выходит из строя.
Порядок операций на самом деле не имеет значения, если вы сначала установите указатель, он может указывать на область памяти, слишком короткую для текущей длины.