如何在新对象中停止goroutine?

时间:2018-06-04 02:52:54

标签: multithreading go parallel-processing goroutine

代码如下:

package main

import (
    "time"
    "runtime"
    "runtime/debug"
)

type obj struct {
}

func getObj() *obj{
    b := new(obj)
    go func() {
        i := 0
        for {
            println(i)
            time.Sleep(time.Second)
            i++
        }
    }()
    return b
}


func main() {
    b := getObj()
    println(b)
    time.Sleep(time.Duration(3)*time.Second)
    b = nil
    runtime.GC()
    debug.FreeOSMemory()
    println("before")
    time.Sleep(time.Duration(10)*time.Second)
    println("after")
}

我创建一个obj,在使用它之后,我想关闭obj中的goroutine,并删除obj以释放内存。 我尝试了runtime.GC()debug.FreeOSMemory(),但它不起作用。

1 个答案:

答案 0 :(得分:4)

添加“完成”频道。 goroutine在每次迭代时检查通道,并在通道关闭时退出。完成后,主goroutine关闭了频道。

type obj struct {
    done chan struct{}  // done is closed when goroutine should exit
}

func getObj() *obj {
    b := &obj{done: make(chan struct{})}
    go func() {
        i := 0
        for {
            select {
            case <-b.done:
                // Channel was closed, exit the goroutine
                return
            default:
                // Channel not closed, keep going
            }
            fmt.Println(i)
            time.Sleep(time.Second)
            i++
        }
    }()
    return b
}

func main() {
    b := getObj()
    fmt.Println(b)
    time.Sleep(time.Duration(3) * time.Second)
    close(b.done) // Signal goroutine to exit
    fmt.Println("before")
    time.Sleep(time.Duration(10) * time.Second)
    fmt.Println("after")
}

Playground example