Go: чтение файла, тупик goroutine - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть два набора кода - для чтения файла со случайными строками текста и загрузки каждой строки в канал. Я не могу понять, почему возвращается ошибка. но другой нет. Случай № 1 возвращает «фатальную ошибку: все программы спят - тупик!» но дело № работает.

Дело № 1

func main () {

file, err := os.Open("/Users/sample/Downloads/wordlist")
if err != nil {
    log.Fatal(err)
}
lines := make (chan string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
    lines <- scanner.Text()
}
close(lines)

for line := range (lines) {
    fmt.Println(line)
}

}

Дело № 2

func main () {

file, err := os.Open("/Users/sample/Downloads/wordlist") 
if err != nil {
    log.Fatal(err)
}
lines := make (chan string)
go func() {
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        lines <- scanner.Text()
    }
    close(lines)
}()

for line := range (lines) {
    fmt.Println(line)
}

}

1 Ответ

1 голос
/ 17 апреля 2019

Отправитель блокируется, пока получатель не получит значение в небуферизованном канале.

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

Например:

queue := make(chan string)
queue <- "one" /* Here main function which is also a goroutine is blocked, because
there is no goroutine to receive the channel value, hence the deadlock*/
close(queue)
for elem := range queue {
    fmt.Println(elem)
}

Это приведет к тупику, и именно это произошло в вашем коде Case # 1 .

Теперь В случае, если у нас есть другие рутины

queue := make(chan string)
go func() {
    queue <- "one" 
    close(queue)
}()
for elem := range queue {
    fmt.Println(elem)
}

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

Это именно так и происходит в вашем случае № 2

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...