package main
import (
"fmt"
"runtime"
"sync"
"time"
)
var c int
func counter() int {
c++
return c
}
func main2() {
a := 100
go func(x, y int) {
time.Sleep(time.Second)
println("go:", x, y)
}(a, counter())
a += 100
println("main:", a, counter())
time.Sleep(time.Second * 3)
}
// 进程退出不会等待并发任务结束,可用通道阻塞,然后发出退出信号
func main3() {
exit := make(chan struct{})
go func() {
time.Sleep(time.Second)
println("goroutine ....")
// 除关闭通道外,写入数据也可接触通道
close(exit)
}()
println("main ....")
<-exit
println("main exit.")
}
// 等待多个并发任务结束,使用sync.WaitGroup
func main4() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1) // 累加计数
go func(id int) {
defer wg.Done() // 递减计数
time.Sleep(time.Second)
println("goroutine", id, "done.")
}(i)
}
println("main ...")
wg.Wait()
println("main exit.")
}
// 可在多处使用wait,它们都能接收到通知
func main5() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
wg.Wait() // 等待归零,解除阻塞
println("wait exit.")
}()
go func() {
time.Sleep(time.Second)
println("done.")
wg.Done()
}()
wg.Wait() // 等待归零,解除阻塞
println("main exit.")
}
func main7() {
var wg sync.WaitGroup
var gs [5]struct {
id int
result int
}
for i := 0; i < len(gs); i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
gs[id].id = id
gs[id].result = (id + 1) * 100
}(i)
}
wg.Wait()
fmt.Printf("%+v\n", gs)
}
// Gosched 暂停,释放线程去执行其他任务。当前任务被放回队列,等待下次调度时恢复执行
func main8() {
runtime.GOMAXPROCS(1)
exit := make(chan struct{})
go func() {
defer close(exit)
go func() {
println("b")
}()
for i := 0; i < 4; i++ {
println("a:", i)
if i == 1 { // 让出当前线程,调度执行 b
runtime.Gosched()
}
}
}()
<-exit
}
// Goexit 立即终止当前任务,运行时确保所有已注册延迟调用被执行
// 无论身处哪一层,Goexit 都能立即终止整个调用栈,这与return仅退出当前函数不同
// 标准库函数 os.Exit 可终止进程,但不会执行延迟调用
func main9() {
exit := make(chan struct{})
go func() {
defer close(exit)
defer println("a")
func() {
defer func() {
println("b", recover() == nil)
}()
func() {
println("c")
runtime.Goexit() // 立即终止整个调用栈
println("c done.")
}()
println("b done.")
}()
println("a done.")
}()
<-exit
}
有疑问加站长微信联系(非本文作者)