go中控制并发的两种方式


当前第2页 返回上一页

在goroutine中,使用select调用<-ctx.Done()判断是否要结束,如果接受到值的话,就可以返回结束goroutine了;如果接收不到,就会继续进行监控。

那么是如何发送结束指令的呢?这就是示例中的cancel函数啦,它是我们调用context.WithCancel(parent)函数生成子Context的时候返回的,第二个返回值就是这个取消函数,它是CancelFunc类型的。我们调用它就可以发出取消指令,然后我们的监控goroutine就会收到信号,就会返回结束。

Context控制多个goroutine

func testMultiContext() {
    ctx, cancel := context.WithCancel(context.Background())
    go watch(ctx, "watch1")
    go watch(ctx, "watch2")

    time.Sleep(10 * time.Second)
    fmt.Println("cancel all goroutine")
    cancel()
    //为了检测监控过是否停止,如果没有监控输出,就表示停止了
    time.Sleep(5 * time.Second)
}

func watch(ctx context.Context, name string)  {
    for {
        select {
        case <-ctx.Done():
            fmt.Println(name," is done")
            return
        default:
            fmt.Println(name," is running")
            time.Sleep(2 * time.Second)
        }
    }
}

Context接口

// A Context carries a deadline, cancelation signal, and request-scoped values
// across API boundaries. Its methods are safe for simultaneous use by multiple
// goroutines.
type Context interface {
    // Done returns a channel that is closed when this Context is canceled
    // or times out.
    Done() <-chan struct{}

    // Err indicates why this context was canceled, after the Done channel
    // is closed.
    Err() error

    // Deadline returns the time when this Context will be canceled, if any.
    Deadline() (deadline time.Time, ok bool)

    // Value returns the value associated with key or nil if none.
    Value(key interface{}) interface{}
}

Context 使用原则

  • 不要把Context放在结构体中,要以参数的方式传递
  • 以Context作为参数的函数方法,应该把Context作为第一个参数,放在第一位。
  • 给一个函数方法传递Context的时候,不要传递nil,如果不知道传递什么,就使用context.TODO
  • Context的Value相关方法应该传递必须的数据,不要什么数据都使用这个传递
  • Context是线程安全的,可以放心的在多个goroutine中传递

参考文献

  • https://blog.golang.org/context

本文来自:简书

感谢作者:cp3_1dbc

查看原文:go中控制并发的两种方式

返回前面的内容

相关阅读 >>

从零实现一个 k-v 存储引擎

Go语言条件语句

【raspberry pi】编译安装etcd集群

关于处理电商系统订单状态的流转,分享下我的技术方案(附带源码)

[系列] Go - 学习 grpc.dial(target string, opts …dialoption) 的写法

关于Go get超时的问题

Golang如何释放map内存?

Golang基础-高级数据结构

Golang可以调用lua吗?

Golang 获取三种不同的路径方法(执行路径,项目路径,文件路径)

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...