go并发-异步和超时控制
Posted 文大侠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go并发-异步和超时控制相关的知识,希望对你有一定的参考价值。
目录
1.异步
go 中可如下实现异步Future功能,异步任务AsyncService返回的是获取数据的管道chan string而不是直接的string调用后立即返回。
GetServiceStatus能允许在返回的管道chan string上等待完成,注意这里要用不带缓冲的管道。
type Task struct {
Test *testing.T
}
func (task *Task) Service() {
task.Test.Log("Service running...")
time.Sleep(time.Second * 5)
task.Test.Log("Service done!")
}
// 需要同步的,可直接返回等待对象
func (task *Task) AsyncService() chan string {
ret := make(chan string)
go func() {
task.Service()
ret <- "done"
}()
return ret
}
// 等待返回,相当于Future -> Get
func (task *Task) GetServiceStatus(sync chan string) string {
ret := <-sync
return ret
}
2.异步超时
前面讲到,返回的是取数据的管道,因此可以很简单实现超时控制,如下
// 支持带超时的Get
func (task *Task) GetServiceStatusWithTimeout(sync chan string, d time.Duration) string {
select {
case ret := <-sync:
return ret
// 超时控制
case <-time.After(d):
return "timeout"
}
}
测试程序如下
task := Task{Test: t}
t.Log("\\n\\nSync task...")
task.Service()
t.Log("\\n\\nASync task...")
sync1 := task.AsyncService()
t.Log(task.GetServiceStatus(sync1))
t.Log("\\n\\nASync task...")
sync2 := task.AsyncService()
t.Log(task.GetServiceStatusWithTimeout(sync2, time.Second*2))
3.context超时
go官方提供通过context控制超时,如下
// CONTEXT控制
var wg sync.WaitGroup
wg.Add(1)
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Task cancel!")
goto END
default:
fmt.Println("Task running...")
time.Sleep(time.Second)
}
}
END:
wg.Done()
}(ctx)
wg.Wait()
原创,转载请注明来自
以上是关于go并发-异步和超时控制的主要内容,如果未能解决你的问题,请参考以下文章
高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可