Go 多个goroutine间协作和传递信息
网络请求Request 需要 goroutine访问后端资源 数据库 RPC服务等 这些goroutine又开启其他的goroutine 如何跟踪和控制这些goroutine
context在多个API和进程之间 实现deadlines截止日期操作 cancelation signals 取消操作 及传递request-scoped 值(即传递参数)
context最大的特点是可以继承 父context 派生子context 子context 又可派生子context 如果父context被取消 子context及其子context都被取消
context 派生方法
有 WithCancel WithDeadline WithTimeout WithValue 其中 WithCancel 主动取消自身以及子context
WithDeadline 和WithTimeout用于超时情况下的取消自身以及子context。WithTimeout实现上直接调用WithDeadline
WithValue用于context传递request-scoped的参数 而不是向函数传递的可选参数
演示控制多个goroutine退出
启动2个goroutine 分别命名为 one two 每个goroutine又启动一个goroutine 就是有4个goroutine
main 调用取消操作cancel 先是one two 收到信号退出
one two 退出的时候又调用它们的cancel 这样所有的goroutine都被取消并退出
package main
import (
"context"
"fmt"
"time"
)
func PrintTask(ctx context.Context, taskName string) {
for {
select {
case <- ctx.Done():
fmt.Println("task:", taskName, " exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, "PrintTask doing something...")
}
}
}
func MainTask(ctx context.Context, taskName string) {
ctx1, cancel := context.WithCancel(ctx)
defer cancel()
newTaskName := taskName + "1"
go PrintTask(ctx1, newTaskName)// create a new task
for {
select {
case <- ctx.Done():
fmt.Println("task:", taskName, " exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, "MainTask doing something...")
}
}
}
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
go MainTask(ctx, "one")
go MainTask(ctx, "two")
time.Sleep(3*time.Second)
cancel()
fmt.Println("main cancel ...")
time.Sleep(3*time.Second)
}//output
task: one MainTask doing something...
task: one1 PrintTask doing something...
task: two MainTask doing something...
task: two1 PrintTask doing something...
task: one1 PrintTask doing something...
task: two MainTask doing something...
task: one MainTask doing something...
task: two1 PrintTask doing something...
main exit...
task: two MainTask doing something...
task: two exit...
task: one1 PrintTask doing something...
task: one1 exit...
task: two1 PrintTask doing something...
task: two1 exit...
task: one MainTask doing something...
task: one exit...
网络请求Request 需要 goroutine访问后端资源 数据库 RPC服务等 这些goroutine又开启其他的goroutine 如何跟踪和控制这些goroutine
context在多个API和进程之间 实现deadlines截止日期操作 cancelation signals 取消操作 及传递request-scoped 值(即传递参数)
context最大的特点是可以继承 父context 派生子context 子context 又可派生子context 如果父context被取消 子context及其子context都被取消
context 派生方法
有 WithCancel WithDeadline WithTimeout WithValue 其中 WithCancel 主动取消自身以及子context
WithDeadline 和WithTimeout用于超时情况下的取消自身以及子context。WithTimeout实现上直接调用WithDeadline
WithValue用于context传递request-scoped的参数 而不是向函数传递的可选参数
演示控制多个goroutine退出
启动2个goroutine 分别命名为 one two 每个goroutine又启动一个goroutine 就是有4个goroutine
main 调用取消操作cancel 先是one two 收到信号退出
one two 退出的时候又调用它们的cancel 这样所有的goroutine都被取消并退出
package main
import (
"context"
"fmt"
"time"
)
func PrintTask(ctx context.Context, taskName string) {
for {
select {
case <- ctx.Done():
fmt.Println("task:", taskName, " exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, "PrintTask doing something...")
}
}
}
func MainTask(ctx context.Context, taskName string) {
ctx1, cancel := context.WithCancel(ctx)
defer cancel()
newTaskName := taskName + "1"
go PrintTask(ctx1, newTaskName)// create a new task
for {
select {
case <- ctx.Done():
fmt.Println("task:", taskName, " exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, "MainTask doing something...")
}
}
}
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
go MainTask(ctx, "one")
go MainTask(ctx, "two")
time.Sleep(3*time.Second)
cancel()
fmt.Println("main cancel ...")
time.Sleep(3*time.Second)
}//output
task: one MainTask doing something...
task: one1 PrintTask doing something...
task: two MainTask doing something...
task: two1 PrintTask doing something...
task: one1 PrintTask doing something...
task: two MainTask doing something...
task: one MainTask doing something...
task: two1 PrintTask doing something...
main exit...
task: two MainTask doing something...
task: two exit...
task: one1 PrintTask doing something...
task: one1 exit...
task: two1 PrintTask doing something...
task: two1 exit...
task: one MainTask doing something...
task: one exit...
尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题