Перейти утечки - PullRequest
       16

Перейти утечки

0 голосов
/ 28 октября 2019

После этого поста об утечке подпрограмм, https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html, я попытался решить свой утечка кода. Но добавление буфера к каналу не помогло.

Мой код

package main

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

func main() {
    fmt.Println(runtime.NumGoroutine())
    leaking()
    time.Sleep(5)
    fmt.Println(runtime.NumGoroutine())
}

func leaking() {
    errChang := make(chan int, 1)
    go func() {
        xx :=  return666()
        errChang <- xx
    }()
    fmt.Println("hola")
    return

    fmt.Println(<-errChang)
}

func return666() int {
    time.Sleep(time.Second * 1)
    return 6
}

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

1 Ответ

1 голос
/ 29 октября 2019

Здесь, на игровой площадке Go , находится ваш оригинальный код с небольшими изменениями:

  • задержки уменьшены, за исключением time.Sleep(5), который становится time.Sleep(time.Second);
  • a return удалено, поскольку оно становится ненужным;
  • a fmt.Println закомментировано, поскольку как return, так и незакомментированное fmt.Println, go vet жалуетсяо недоступном fmt.Println;
  • канал, сохраненный в errChang, изменяется на небуферизованный.

При запуске его вывод:

1
hola
2

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

Если мы раскомментируем закомментированный fmt.Println, вывод:

1
hola
6
1

(с такой же небольшой задержкой перед окончательным 1), потому что теперь мы ждем (а затем печатаем) значение, вычисленное в return666 и отправленное по каналуerrChang.

Если мы оставим закомментированный fmt.Println закомментированным и сделаем канал buf* * * * * * , вывод будет:

1
hola
1

, так как анонимная программа теперь может выдвинуть свое значение (6) в канал.

Сам канал будет собирать мусор,вместе с единственным значением, хранящимся внутри него, так как на данный момент нет никаких ссылок на канал. Однако обратите внимание, что простого создания буферизованного канала не всегда достаточно. Если мы отправим два значения по каналу , программа вернется к печати:

1
hola
2

, когда анонимная программа успешно вставит 6 в канал, но затем блокирует попытку вставить 42 в том числе.

...