пытаюсь понять, что golang chan вызывает сбой или делает что-то еще

#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 может сначала прочитать новую длину и старый указатель. Затем он пытается прочитать конец предыдущей строки. Он либо считывает какой-то мусор, либо останавливается операционной системой и выходит из строя.

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