go并发-异步和超时控制

Posted 文大侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go并发-异步和超时控制相关的知识,希望对你有一定的参考价值。

目录

1.异步

2.异步超时

3.context超时


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并发-异步和超时控制的主要内容,如果未能解决你的问题,请参考以下文章

go并发-异步和超时控制

GO语言入门第五节 Go语言的并发编程

每天遇到的零散知识汇聚

高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可

Go并发模型:超时,继续(Timing out, moving on译文)

Go并发模型:超时,继续(Timing out, moving on译文)