美文网首页
go cancel goroutine 的执行

go cancel goroutine 的执行

作者: lesliefang | 来源:发表于2017-12-02 20:47 被阅读217次

    没有任何显示方法可以终止一个 goroutine 的执行
    要终止一个 goroutine 的执行,我们需要给 goroutine 一个结束运行的信号,当然用 channel 可以实现

    package main
    
    import "fmt"
    import "time"
    import "sync"
    import "os"
    
    func main() {
        var wg sync.WaitGroup
        var abort = make(chan int)
    
        go func() {
            os.Stdin.Read(make([]byte, 1)) // 按 enter 建结束
            abort <- 0
        }()
    
        wg.Add(1)
        go func() {
            defer wg.Done()
            for {
                select {
                case <-abort:
                    return
                default:
                    // do real things
                    time.Sleep(1 * time.Second)
                    fmt.Println("go routine running...")
                }
            }
        }()
    
        wg.Wait()
        fmt.Println("main exists")
    }
    
    

    wg 是让主线程等待的,可暂时忽略

    我们只需要发一个 abort 信号,goroutine 就结束运行
    但当有多个 goroutine 需要终止时我们要定义多个 abort

    其实没必要 send 直接 close 掉 abort 就行了,一个 channel 被 close(且 drained) 以后再取值就不会阻塞了而是直接返回零值。这样就可以同时终止多个 goroutine 的执行了

    package main
    
    import (
        "fmt"
        "os"
        "sync"
        "time"
    )
    
    var wg sync.WaitGroup
    var done = make(chan struct{})
    
    // help method not used here
    func cancelled() bool {
        select {
        case <-done:
            return true
        default:
            return false
        }
    }
    
    func worker1() {
        defer wg.Done()
        for {
            select {
            case <-done:
                return
            default:
                // do real things
                time.Sleep(1 * time.Second)
                fmt.Println("worker1 running...")
            }
        }
    }
    
    func worker2() {
        defer wg.Done()
        for {
            select {
            case <-done:
                return
            default:
                // do real things
                time.Sleep(1 * time.Second)
                fmt.Println("worker2 running...")
            }
        }
    }
    
    func main() {
        go func() {
            os.Stdin.Read(make([]byte, 1)) // 按 enter 建结束
            close(done)
        }()
    
        wg.Add(2)
        go worker1()
        go worker2()
    
        wg.Wait()
        fmt.Println("main exists")
    }
    

    相关文章

      网友评论

          本文标题:go cancel goroutine 的执行

          本文链接:https://www.haomeiwen.com/subject/ezcobxtx.html