go cancel goroutine 的执行

没有任何显示方法可以终止一个 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 的执行)