SoFunction
Updated on 2025-03-04

The use and concurrency control of Context packages in Golang concurrent programming

1. Introduction

In concurrent programming, task management and resource control are very important, andGolang'scontextBagProvides us with an elegant way toPass a cancel signalandTimeout controlContextUsed 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 detailcontextUsage of packages and explain through examples how to useTimeout, cancel taskandMulti-Goroutine collaborationUse it in the scene.

2. The basic concept of Context

ContextIt'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 calledcancel()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:

  • passThe 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

WithDeadlineandWithTimeoutSimilarly, 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.WithValueAllows 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:

WithValueAllow us to set the contextKey-value pairs, facilitates data transfer between multiple Goroutines.

Notice:

Not recommendedWithValuePass 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:useWithTimeoutandWithCancelTerminate 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!