This is a creation in Article, where the information may have evolved or changed.
Context
The package (context) type is a control mechanism that wraps the channel communication to correlate Goroutine services, supports tree-like superiors to control one or more subordinates, does not support reverse control and peace-level control, and the sharing of empathy parameters is a tree-like flow direction, It can also be used to manage functions with timeout dependencies, in the following code instance, where there is a forever for loop to calculate the service.
Parameter sharing features
- The context parameter store is not a map, is a struct key and Val two properties, externally exposed operation interface
- The parameters of the context are initialized by the parent goroutine, and the child goroutine is called
- The parent context embeds a sub-context, with the same name parameter having multiple versions
- The sub-context fetch parameter obtains the multi-level parent context parameter according to embed's upward lookup mechanism, and the parameter version of the child context takes precedence with the same name parameter
- Child context Initializes a parameter other than the same name, equivalent to adding a new parameter
- Child context Initializes a parameter with the same name, which is equivalent to adding a parameter version
- Context Pass the Parameters note Select the necessary, simple, small size
- The context is gorountine safe because it is read-only, and multiple child gorountine services can share the parent control of the same context
Control features
- The parent Gorountine service is implemented through the context control sub-gorountine service by the empty channel inside the struct, the parent Gorountine service close the empty channel, Select Listener for the sub-gorountine service and may trigger a shutdown event to end the lifecycle
- The parent Gorountine service reaches a certain state, transmits a signal, ends the sub-gorountine service
- When the parent Gorountine service initializes the child Gorountine service, the incoming cutoff time or timeout
- The parent gorountine ends, then all the sub-gorountine services end
- The above three rules collectively determine the life cycle of a gorountine service
Use
123456 |
type Interface {Done () <-chanstruct//control the life cycle of the empty channel //Get error code BOOL //Get cut-off time interfaceinterface//pass Parameters } |
The contextual context of the Goroutine service is derived from the content of the parent Withvalue service through Withcancel, Withdeadline, Withtimeout, Goroutine, deriving a new context. Cancelfunc can cancel all descendants, remove the association of the parent Goroutine service in the child Goroutine service, and stop all associated timer.
1234567891011 |
Package mainImport"context"functree() { ctx1: = Context. Background () ctx2, _: = Context. Withcancel (CTX1) 5) 3) 6) "UserID"12 )} |
The context chain for the above code:
3-second timeout: ctx4 timeout exit
5-second timeout: Ctx3 timed out, causing child nodes ctx5 and ctx6 to exit
Here is only the image of the multi-level context of the formation of the control relationship between the actual business inside the ctx5,ctx6 Goroutine if the implementation of the business is not immediately exit, Only case where Goroutine is terminated by the select response while waiting for the IO event to wait for data.
Background and Todo
They're all returning the same. Empty context,background without parameters in the main service normally generates a controllable Context variable as an anonymous parameter; Todo may be used for program compatibility processing, overhead piles, air conditioning
Withcancel
Passes in the parent context, returns the controllable child context, and returns the control function that ends the goroutine of the calling child context
12345678910111213141516171819202122232425262728293031 |
//func Withcancel (the parent context) (CTX context, cancel Cancelfunc) PackageMainImport "Context" func main() {Gen: = func(ctx context. Context) <-chan int {DST: = Make(Chan int) N: =1 Go func() { for{the//for loop is the flag of the Goroutine function as a service Select{ Case<-ctx. Done ():return CaseDST <-N://The blockage here may become a function of the timeout dependencyN++}}} ()returnDST} ctx, Cancel: = context. Withcancel (context. Background ())deferCancel ()//Be sure to manually add the cancel Operation forN: =RangeGen (CTX) {println(n)ifn = =5{ Break} }} |
Withdeadline
Passes in the parent context and deadline, returns a controlled sub-context containing the deadline, and returns the control function that ends the goroutine that invokes the child context
1234567891011121314151617 |
//func Withdeadline (parent Context, Deadline time. Time) (context, Cancelfunc) Package mainImport"context"import"Time" funcmain() { D: = time. Now (). ADD ( * time.millisecond) ctx, Cancel: = context. Withdeadline (context. Background (), D) defer cancel () Select {case <-time. After (1 * time. Second): println("overslept") case <-ctx. Done (): println(ctx. ERR ()) }} |
Withtimeout
Passes in the parent context and time-out, returns a controllable child context with a time-out, and returns a control function that ends the goroutine that invokes the child context
1 |
Func withtimeout (parent Context, timeout time. Duration) (Context, Cancelfunc) |
Withvalue
Passes in the parent context and parameter key-val, returns the child context that contains the parameter, if the parent context is background, then the child context is not controllable, otherwise controllable
- Inside the service context. Background (), which is not suitable as a parameter of the Withvalue to receive the variable, can be CTX: = context. Withcancel (context. Withvalue (context. Background (), K, "Go")
- The context key is a global variable within the package and cannot be exported to avoid conflicts
- The data type of the context key must support = = and! =, similar to the map key, including Bool,number,string,pointer,channel,interface and the array,struct containing the above types. Slice,map,function or types that contain them are not supported.
- The data stored is best Type-safe
1234567891011121314151617181920212223 |
//func Withvalue (parent context, key, Val interface{}) Context PackageMainImport "Context" func main() {typeFavcontextkeystringF: = func(ctx context. Context, K favcontextkey) {ifV: = ctx. Value (k); V! =Nil{println("Found value:", V)return}println("Key not found:", K)} k: = Favcontextkey ("Language"CTX: = Context. Withvalue (context. Background (), K,"Go") F (CTX, K) F (CTX, Favcontextkey ("Color"))} |
The Go Vet tool can check the usage of Cancelfuncs. The context parameter is not wrapped in a struct and other complex data structures, the context parameter position placed in the function of the first variable, the context parameter do not pass nil.
Problem
How to achieve peer control, one sub-goroutine problem and the other sub-goroutine that share the parent control are removed, see Golang.org/x/sync/errgroup
To avoid allocating if assigning to an interface{}, context keys often has concrete type struct{}. Alternatively, exported context key variables ' static type should be a pointer or interface. What does this mean?