Home  >  Article  >  Backend Development  >  An in-depth introduction to the usage of Golang context

An in-depth introduction to the usage of Golang context

PHPz
PHPzOriginal
2023-04-11 09:14:041211browse

Golang is a powerful programming language that is efficient and concise and is currently developing rapidly. When writing Go code, each function's input and output parameters have their own life cycle. When multiple Goroutines are running at the same time, we may need to manage the context to ensure the correctness of the program. This is the role of Golang context. In this article, we will introduce the usage of Golang context.

1. The concept of Golang Context

Golang Context is an object containing relevant values ​​within the request range. This object can be passed between functions and provides support for cancellation operations. For example, when processing Http requests, we can use the context package to pass the Http request as a parameter to obtain the request-related context.

The structure definition of Golang Context is as follows:

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}

The definition of the above structure includes the Deadline, Done, Err and Value methods. Below we will introduce their functions one by one.

2. Use of Golang Context

  1. Deadline method

The Deadline method returns a time and a Boolean value. When the context is canceled or reaches its deadline, the context returns this time and a Boolean value of true, otherwise it returns false. Some contexts do not have a deadline, in which case the Deadline method will return false.

func main() {
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5))
    defer cancel()
    
    select {
    case <-time.After(3 * time.Second):
        fmt.Println("等待了3秒钟")
    case <-ctx.Done():
        fmt.Println(ctx.Err())
    }
}

In the above code, first we create a Context with a Deadline whose deadline is 5 seconds after the current time. Then we use the select statement to wait for 3 seconds. At this time we will find that the program is still waiting, because the waiting time does not exceed the Deadline. Finally, when the deadline is exceeded, the program will end due to the return value of ctx.Done().

  1. Done method

The Done method returns a read-only channel. This channel will be closed when the context is canceled or the deadline is reached. Therefore, we can use the select statement and Done method in our code to monitor the status of the Context.

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go func(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println(ctx.Err())
                return
            default:
                fmt.Println("goroutine正在运行中...")
                time.Sleep(1 * time.Second)
            }
        }
    }(ctx)

    // 模拟耗时操作
    time.Sleep(5 * time.Second)
    cancel() // 取消Context
    time.Sleep(3 * time.Second)
    fmt.Println("main函数执行结束")
}

In the above code, we use the WithCancel and cancel functions to start and end the Context, and print logs regularly in a goroutine until the Context is canceled. At the same time, we use Sleep to simulate a time-consuming operation. The current function calls the cancel function after 5 seconds, terminating the Context and thus ending the entire program.

  1. Err method

The Err method returns the reason why the Context was canceled. For a canceled Context, this method will return a non-null error value. If the Context has not been canceled, the Err method will return nil.

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go func(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println(ctx.Err())
                return
            default:
                fmt.Println("goroutine正在运行中...")
                time.Sleep(1 * time.Second)
            }
        }
    }(ctx)

    // 模拟耗时操作
    time.Sleep(5 * time.Second)
    cancel() // 取消Context
    time.Sleep(3 * time.Second)
    fmt.Println("main函数执行结束")
}

In the above code, the Err method is used in the goroutine, which returns the reason for cancellation. Finally, we print "main function execution ended" in the main function.

  1. Value method

The Value method returns the value associated with Context, which is an object of type interface{}. You can set any type of value in the Context and use the Value method to get the value in subsequent operations.

type authKey string
func main() {
    ctx := context.WithValue(context.Background(), authKey("token"), "123456")
    fmt.Println(ctx.Value(authKey("token"))) // 打印"123456"
}

In the above code, we use the WithValue method to associate a string type value with Context, and use the Value method to obtain the value.

3. Summary

Golang Context is an important part of handling concurrent code. By passing Context between functions, we can manage the life cycle in the code, and we can also monitor the status of Context through methods such as Done, Err, and Value. Mastering the use of Golang Context can improve the quality and concurrency of your code.

The above is the detailed content of An in-depth introduction to the usage of Golang context. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn