Go中如何使用context实现跨goroutine通信

1. 什么是context?

Context是Go语言提供的一种用来传递请求范围内变量、取消操作以及处理超时等的机制。在并发编程中,通常情况下都需要实现多个goroutine之间的协调和通信。Context则是在这种情况下的一种很便捷的选择。

Context的主要注意点:

Context是线程安全的。

Context可以被析构。

Context.Value返回的是一个空interface类型,需要类型断言。

2. Context使用示例

2.1 在Context中传递值

Context的最常见用途就是在多个goroutine之间传递请求的上下文信息。context包提供了WithValue操作,该操作可以将key-value键值对存储到Context变量中。

package main

import (

"context"

"fmt"

)

type key int

const myKey key = 0

func main() {

ctx := context.WithValue(context.Background(), myKey, "Hello World")

value := ctx.Value(myKey)

fmt.Println(value)

}

在这个示例中,我们初始化了context,然后通过WithValue函数设置了一组key-value键值对,key的类型是一个自定义的类型myKey,value是"Hello World"字符串。最后我们通过ctx.Value方法查询了这个值。

2.2 在Context中取消操作

在编写复杂应用程序时,有时候我们需要在一组并行goroutine中发送取消信号。Context类支持这个需求,我们可以通过上下文的CancelFunc完成这个操作。

package main

import (

"context"

"fmt"

)

func main() {

ctx, cancel := context.WithCancel(context.Background())

go func() {

select {

case <-ctx.Done():

fmt.Println(ctx.Err())

}

}()

cancel()

select {}

}

在这个示例中,我们使用context.WithCancel函数设置了一个上下文。然后我们在新的goroutine中监听ctx.Done方法返回的信号,如果信号被触发,则输出ctx.Err()返回的内容。接着使用cancel函数发送了取消信号。

2.3 Context同步

Context可以实现多个goroutine之间的同步操作。我们可以使用WithCancel或者WithTimeout等操作中的一种,来构建一个Context,而后通过WaitGroup,来等待relateGoroutine完成相应的任务,一直到任务完成为止。

package main

import (

"context"

"fmt"

"sync"

"time"

)

func task(ctx context.Context, wg *sync.WaitGroup) error {

defer wg.Done()

for {

select {

default:

fmt.Println("Working...")

time.Sleep(100 * time.Millisecond)

case <-ctx.Done():

return ctx.Err()

}

}

}

func main() {

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)

defer cancel()

var wg sync.WaitGroup

for i := 0; i < 10; i++ {

wg.Add(1)

go task(ctx, &wg)

}

wg.Wait()

}

在这个示例中,我们使用WithTimeout函数设置了一个上下文,并限定了最长运行时间为3秒。然后我们通过WaitGroup实现多个goroutine的同步,并让所有goroutine都执行完task函数。

3. Context小结

通过本文的讲解,我们了解了Context在协调goroutine之间的通信和请求上下文中的有用性。我们可以通过WithValue、WithCancel、WithTimeout等方法实现context的相关操作。Context的运用可以大大提高代码的简洁度和可读性。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签