1. Introduction
In concurrent programming, task management and resource control are very important, andGolang'scontext
BagProvides us with an elegant way toPass a cancel signalandTimeout control。Context
Used to pass between multiple GoroutinesContext information, avoiding the waste of resources caused by Goroutine's inability to stop as needed.
This blog will introduce in detailcontext
Usage of packages and explain through examples how to useTimeout, cancel taskandMulti-Goroutine collaborationUse it in the scene.
2. The basic concept of Context
Context
It's a kindCarry cancel signal, deadline (timeout) and metadatacontext object, mainly used forCollaboration between parent Goroutine and child Goroutine. It passesHierarchical structureto manage multiple concurrent tasks.
1. Context package commonly used functions
-
()
: Create a root context, usually used for program entry. -
()
: Placeholder context, indicating that the future will be replaced by the actual following. -
(parent Context)
: Create a subcontext with cancel function. -
(parent Context, timeout )
: Create a subcontext with timeout function. -
(parent Context, deadline )
: Creates a context based on the specified deadline. -
(parent Context, key, value interface{})
: Passing a context that carries extra data.
3. Basic usage of Context
1. WithCancel: The context of canceling the task
Example: UseWithCancel
Cancel Goroutine
package main import ( "context" "fmt" "time" ) func worker(ctx , id int) { for { select { case <-(): // Receive cancel signal ("Worker %d stopped\n", id) return default: ("Worker %d is working...\n", id) () } } } func main() { ctx, cancel := (()) // Create a cancelable context for i := 1; i <= 3; i++ { go worker(ctx, i) } (3 * ) // Other jobs of Simulation Master Goroutine ("Cancelling all workers...") cancel() // Send a cancel signal (1 * ) // Wait for all Goroutines to exit ("All workers stopped.") }
Output:
Worker 1 is working...
Worker 2 is working...
Worker 3 is working...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.
Analysis:
The created context can be called
cancel()
sendCancel signal, thus gracefully stopping all sub-Goroutines.
4. Timeout control: WithTimeout and WithDeadline
1. Use WithTimeout to control task timeout
Example: Complete the task within 2 seconds, otherwise exit timeout
package main import ( "context" "fmt" "time" ) func worker(ctx ) { select { case <-(3 * ): // Simulate long-term tasks ("Task completed") case <-(): // Receive timeout signal ("Task timed out") } } func main() { ctx, cancel := ((), 2*) // Set 2 seconds timeout defer cancel() // Ensure resource release go worker(ctx) (4 * ) // Wait for the task to complete or time out}
Output:
Task timed out
Analysis:
- pass
The created context will automatically send a cancel signal when the task is not completed within 2 seconds.
- Timeout context avoids GoroutineRun indefinitely, help better manage resources.
2. Use WithDeadline to set the deadline
WithDeadline
andWithTimeout
Similarly, just use specific time points to control the timeout.
5. Pass the data in the context: WithValue
Sometimes we need to pass some metadata between multiple Goroutines.WithValue
Allows us to save key-value pairs into context and access them in sub-Goroutines.
Example: Passing user information
package main import ( "context" "fmt" "time" ) func greetUser(ctx ) { if user, ok := ("user").(string); ok { ("Hello, %s!\n", user) } else { ("No user found.") } } func main() { ctx := ((), "user", "Alice") //Storing user information in the context go greetUser(ctx) (1 * ) // Make sure that the Goroutine is executed}
Output:
Hello, Alice!
Analysis:
WithValue
Allow us to set the contextKey-value pairs, facilitates data transfer between multiple Goroutines.
Notice:
Not recommendedWithValue
Pass important control information, such as cancel signal or timeout.
6. Application scenarios of Context
- Timeout control of API requests: Ensure that HTTP requests do not wait indefinitely.
- Mission cancellation: When the user proactively cancels an operation, the relevant Goroutine is notified to stop working.
- Passing metadata: For example, passing information such as user identity, request ID, etc. in the service link.
7. Complete example: Multitasking Collaborative Control
Example: Start multiple tasks, and cancel all tasks at any time
package main import ( "context" "fmt" "sync" "time" ) func worker(ctx , id int, wg *) { defer () for { select { case <-(): ("Worker %d stopped\n", id) return default: ("Worker %d is processing...\n", id) (500 * ) } } } func main() { var wg ctx, cancel := (()) // Create a context for i := 1; i <= 3; i++ { (1) go worker(ctx, i, &wg) } (2 * ) ("Cancelling all workers...") cancel() // Cancel all tasks () // Wait for all tasks to complete ("All workers stopped.") }
Output:
Worker 1 is processing...
Worker 2 is processing...
Worker 3 is processing...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.
8. Summary
- Context for concurrent control: Pass a cancel signal, a timeout signal, or carries metadata in the Goroutine.
-
Timeout control and resource management:use
WithTimeout
andWithCancel
Terminate tasks in a timely manner to avoid wasting resources. - Multi-Goroutine collaboration: Enable elegant communication between multiple Goroutines through Context.
This is the article about the use and concurrency control of the Context package in Golang concurrent programming. For more information about the use of the Golang Context package, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!