GoでLuaのコルーチンやRubyのFiberのような機能を再現したいのですが、良い方法が思いつきません。

以下のようにGoroutineを使うと、似たようなことは可能ですが問題があります。

package main

import "fmt"

func main(){
    ch := make (chan int)

    go func() {
        i := 0
        for {
            ch <- i
            i++
        }
    }()

    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

LuaやRubyでは、resumeできる状態であってもコルーチンはGCの対象になります。 しかし、Goではブロック中のGoroutineがGCの対象にならないため、メモリリークが発生してしまいます。

以下の例では、chはGoroutineの中でしか参照されないためブロックの解除は永久に発生しない状況ですが、Goroutineは残ったままです。

package main

import (
    "runtime"
    "fmt"
)

func main(){
    for {
        go func(ch <-chan int) {
            <-ch
        }(make(chan int))
        runtime.GC()
        fmt.Println(runtime.NumGoroutine())
    }
}

何か良い解決方法はないでしょうか。