Почему чтение с нулевого канала увеличивает количество Goroutines? - PullRequest
0 голосов
/ 14 марта 2020

Я читаю этот блог, https://medium.com/golangspec/goroutine-leak-400063aef468, и адаптировал следующий пример, иллюстрирующий утечку горутина из-за приема по нулевому каналу:

package main

import (
    "flag"
    "fmt"
    "runtime"
    "time"
)

var initChannel bool

func main() {
    flag.Parse()

    var ch chan int
    if initChannel {
        ch = make(chan int, 1)
        ch <- 1
    }
    go func(ch chan int) {
        <-ch
    }(ch)

    c := time.Tick(1 * time.Second)
    for range c {
        fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())
    }
}

func init() {
    flag.BoolVar(&initChannel, "init", false, "initialize channel")
}

У меня есть заметил, что, если я запускаю его с initChannel false, число процедур составляет 2:

> go run main.go
#goroutines: 2
#goroutines: 2

, тогда как если я запускаю его с true, число равно 1:

> go run main.go --init
#goroutines: 1
#goroutines: 1

Однако я не совсем понимаю, почему это так. Я вижу только один оператор go, поэтому я ожидаю, что в любом случае будет только одна программа. Почему при чтении с нулевого канала есть две функции?

1 Ответ

3 голосов
/ 14 марта 2020

Когда ваше приложение запускается, уже есть одна процедура, которая выполняет функцию main().

Если вы не инициализируете канал ch, он останется нулевым значением что составляет nil для каналов. Spe c: Оператор получения:

Прием из nil блоков каналов навсегда.

Подробнее см. Как ведет себя неинициализированный канал?

Так что, если канал nil, запущенная программа никогда не закончится. Таким образом, у вас будет 2 подпрограммы: main и подпрограмма, которую вы запустили.

Если вы инициализируете канал с 1 буфером и отправите на него одно значение, то у вас также будет 2 подпрограммы для короткой строки. период времени ", но запущенная программа может получить значение из нее и затем немедленно завершить. Таким образом, останется одна подпрограмма, main подпрограмма.

...