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