简体   繁体   中英

How can I stop the goroutine in the New Object?

The code is as follows:

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")
}

I create an obj, after using it, I want to close the goroutine in the obj, and delete the obj to free the memory. I tried the runtime.GC() and debug.FreeOSMemory() , but it doesn't work.

Add a "done" channel. The goroutine checks the channel on each iteration and exits when the channel is closed. The main goroutine closes the channel when done.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM