阅读背景:

Context学习_Linzhongyilisha的专栏

来源:互联网 

 

WithCancel实例: 

package main

import (
	"context"
	"fmt"
)

/*
Context 包定义了上下文类型,该上下文类型跨越 API 边界和进程之间传递截止期限,取消信号和其他请求范围值。

对服务器的传入请求应创建一个 Context,对服务器的传出调用应接受 Context。它们之间的函数调用链必须传播 Context,可以用使用 WithCancel,WithDeadline,WithTimeout 或WithValue创建的派生上下文替换。当 Context 被取消时,从它派生的所有 Context 也被取消。

WithCancel,WithDeadline 和 WithTimeout 函数采用Context(父级)并返回派生的Context(子级)和CancelFunc。调用 CancelFunc 将取消子对象及其子对象,删除父对子对象的引用,并停止任何关联的定时器。未能调用CancelFunc 会泄漏子项及其子项,直至父项被取消或计时器激发。go vet 工具检查在所有控制流路径上使用 CancelFuncs。

使用 Contexts 的程序应该遵循这些规则来保持包之间的接口一致,并使静态分析工具能够检查上下文传播:


不要将上下文存储在结构类型中;相反,将一个 Context 明确地传递给每个需要它的函数。上下文应该是第一个参数,通常命名为 ctx

*/
func main() {
	// Create a new cancellable context from a new blank context.
	//
	// WithCancel returns a copy of parent with a new Done channel. The returned
	// context's Done channel is closed when the returned cancel function is called
	// or when the parent context's Done channel is closed, whichever happens first.
	//
	// Canceling this context releases resources associated with it, so code should
	// call cancel as soon as the operations running in this Context complete.
	//
	// Background returns a non-nil, empty Context. It is never canceled, has no
	// values, and has no deadline. It is typically used by the main function,
	// initialization, and tests, and as the top-level Context for incoming
	// requests.
	ctx, cancel := context.WithCancel(context.Background())

	// Even though ctx should have been cancelled already, it is good
	// practice to call its cancelation function in any case.
	// Failure to do so may keep the context and its parent alive
	// longer than necessary.
	defer cancel()

	// Create a new message channel.
	msg := make(chan string)

	// Call fnc 10 times in their own goroutines.
	for i := 0; i < 10; i++ {
		go fnc(i, msg, ctx, cancel)
	}

	// Receive and print a single message from the msg channel.
	fmt.Println(<-msg)

	// Wait until the cotext is cancelled before exiting main.
	<-ctx.Done()
}

// fnc takes in an integer, message string channel, a context and also a cancel function
// for that context.
func fnc(i int, msg chan string, ctx context.Context, cancel context.CancelFunc) {
	select {
	// Check if the context was already cancelled.
	//
	// Done returns a channel that's closed when work done on behalf of this
	// context should be canceled. Done may return nil if this context can
	// never be canceled. Successive calls to Done return the same value.
	//
	// WithCancel arranges for Done to be closed when cancel is called;
	// WithDeadline arranges for Done to be closed when the deadline
	// expires; WithTimeout arranges for Done to be closed when the timeout
	// elapses.
	case <-ctx.Done():
		fmt.Printf("fnc %d cancelled\n", i)
		return
	// Send a string on the msg channel and then cancel the context so the
	// other goroutines exit cleanly.
	case msg <- fmt.Sprintf("fnc %d finished first\n", i):
		cancel()
	}
}
package main

import



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: