SoFunction
Updated on 2025-04-09

Instructions for using context in go language

Overview

ContextIt is a very important concept in the Go language, which is mainly used to pass across multiple functions or goroutines.Cancel signalTimeout controlDeadlineandRequest scope data

In concurrent programming,ContextProvides better control and management, especially when you need to pass state between multiple goroutines or perform resource cleaning.

Main functions

ContextIt has the following functions:

  • Cancel signal: Notify one or more goroutines to cancel the work they are performing.
  • Timeout and deadline: Specify the maximum execution time of the operation to prevent blocking operations from being too long.
  • Pass request range data: Carry data within the request scope, usually used for request ID, user information, etc.

Three basic types of Context

In GocontextThe package provides several commonly used onesContexttype:

  • (): Usually as rootContext, indicates that there is no additional data or cancel signal context. It is usually the root context, as the parent context of other contexts.
  • (): It means you are not sure what to useContext, usually used for placeholding.
  • (parent): Create a cancelableContextand return a cancel function, when you call this function,ContextWill be cancelled.
  • (parent, timeout): Create a timeoutContext, specify the maximum waiting time, and it will be automatically cancelled after this time.
  • (parent, deadline): Specify a specific deadline, which will be automatically cancelled after this time exceeds.
  • (parent, key, value): Create a key-value pair dataContext, is usually used to pass request level data (for example, user identity information).

Common usage examples

Pass a cancel signal

Main scenarios:

  • Manually control the termination of concurrent tasks
  • Elegant Exit: When a task needs to be cancelled midway, usecancel()Notify all relevant goroutines to stop execution.

Code example:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// Create a cancelable Context	ctx, cancel := (())

	// Start a goroutine and listen for cancel signal	go func(ctx ) {
		for {
			select {
			case <-(): // Cancel signal was detected				("Goroutine stopped")
				return
			default:
				// Simulation work				("Working...")
				(1 * )
			}
		}
	}(ctx)

	// The main thread waits for 3 seconds and cancels	(3 * )
	cancel() // Send a cancel signal
	// Wait for goroutine to exit	(1 * )
	("Main program exited")
}

explain

  1. The main thread creates a context with cancel functionctx
  2. sub goroutine use()Listen to cancel signal.
  3. Main thread is called after 3 secondscancel(), sub-goroutine exits gracefully after detecting the signal.

Set timeout using WithTimeout

Used to set a timeout time after which time is exceededContextIt will be cancelled automatically and is suitable for operations that require a limited time. Prevent some tasks from blocking for too long.

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// Set the timeout to 2 seconds	ctx, cancel := ((), 2*)
	defer cancel() // Make sure to cancel ctx after timeout
	// Start a task that simulates long-term execution	go longRunningTask(ctx)

	// Wait for timeout or task completion	<-()
	if () ==  {
		("Timeout reached")
	}
}

func longRunningTask(ctx ) {
	select {
	case <-(3 * ): // Simulate long-term tasks		("Task completed")
	case <-():
		// The task is cancelled or timed out		("Task cancelled due to timeout")
	}
}

WithDeadlineUsage andWithtimeoutThe usage is similar, except that an incoming parameter is the waiting time and an incoming parameter is the deadline.

Passing data using WithValue

Can beContextKey-value pairs are stored in it, which are usually used to pass request-level data (such as user identity, request ID, etc.).

package main

import (
	"context"
	"fmt"
)

func main() {
	// Create a context and pass data	ctx := ((), "userID", 12345)

	// Pass ctx to other functions	processRequest(ctx)
}

func processRequest(ctx ) {
	// Extract data from ctx	userID := ("userID")
	if userID != nil {
		("User ID:", userID)
	} else {
		("No user ID found")
	}
}

useWithValue carefulIt is not used to pass a large amount of data, but is mainly used to pass a small amount of context information, such as request ID, etc.

If too much data is passed, it will makeContextDifficult to maintain.

Commonly used related methods and constants

  • (): Return a channel, whenContextThe channel will be closed when cancelled.
  • ():returnContextThe canceled error is usuallyor
  • (key): Get it inContextdata passed in.

How to control the execution of goroutine

From the above example, we can see that in each goroutine, whether () is executed, we know whether the task is cancelled/timed out/reached the deadline.

whenContextCancel (callcancel()) or timeout/when the deadline is reached,()The associated channel will be closed, and the select statement can be executed at this time.()Corresponding branch.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.