网站开发组合 所有组合在哪个网站去租地方做收废站
news/
2025/9/30 3:06:44/
文章来源:
网站开发组合 所有组合,在哪个网站去租地方做收废站,网络推广方式和方法,免费网站制作教程前言
在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background().
但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中…前言
在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background().
但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中的一个共识, 一个基础元素. 除了context.Background()一定还有其他的值, 否则也不会作为参数来接收了.
用了这么久, 都不知道它的作用, 这实在有点说不过去了, 于是抽时间来好好研究研究context在Golang中的作用.
作用
在Golang源码包中, context.go很贴心的给出来官网介绍的文章: https://blog.golang.org/context
在Golang中, 协程被设计为非常方便且轻量的用户态线程, 鼓励我们使用协程来完成各种耗时的操作.
假设, 有一个处理请求A的goroutine, 其同时又启动了n个额外的goroutine来协助操作. 此时, 若请求 A被取消, 那么所有相关的资源都需要被释放, 所有处理该请求的goroutine都应该快速退出, 防止造成资源的浪费. 那么问题来了, parent是无法主动关闭子协程的, 如何通知子协程需要提前退出呢?
我想了想, 这不就是多协程之间的通信么, 这块我熟啊. 用锁, 用管道, 用什么都行, 只要将取消的消息群发给所有子协程就可以了, 随便列举几个方案:
共享变量. 通过共享一个bool变量, 子协程定期检测变量值来判断是否需要退出管道. 子协程定期检测管道是否关闭来判断是否需要退出等等
没错了, Context就是干这个用的. 它提出来的主要目的, 就是提醒子协程该退出了. 而它实现的原理也是通过协程通信实现的, 只是在其上面封了一层, 以方便调用.
虽然Context在刚开始的时候只是为了封装子协程的退出提醒(只是我的猜测), 但是既然都加上下文了, 自然得带点上下文环境变量了. 其作用通过Context接口暴露的方法可窥见一二:
Deadline() (deadline time.Time, ok bool) 返回工作的截止时间. (若没有, 则 okfalse) Done() -chan struct{} 返回一个管道. 若从管道中可以读到数据, 说明任务被关闭了. (若不需要, 返回 nil)通常做法为在需要退出时将管道关闭. Err() error 返回任务被关闭的原因. Value(key any) any 返回上下文包含的环境变量
因此, Context其实只能够干两件事
通知子协程提前退出携带环境变量
context 包
Golang的context包除了测试文件, 仅contxt.go一个文件. 且, 将context.go文件中的注释和空行去掉之后, 整个文件代码仅318行(使用版本为 go 1.18), 称得上短小精悍了. 这里就不分析源码了, 感兴趣的自己看一下, 简单整理一些context包中包含的内容:
官方已实现的常用Context结构体, 均为私有结构体, 需要使用下方的方法生成, 官方仅实现了常用的几个实例, 这几个实例可组合使用, 若不能满足自己需求也可以自己实现:
名称作用emptyCtx空的Context, 所有接口实现均为空实现. 既永远不会停止cancelCtx可以被主动取消的Context. parent调用特定方法进行取消timerCtx定时器, 在指定时间后取消valueCtx永远不会停止, 用来传递上下文环境变量
context包中提供的公共方法, 我们通常调用的就是这些了, 可以看到, 官方提供的生成方法, 都是基于一个已有的context基础上进行生成, 也就是说我们在使用的时候可以进行组合, 将前一个生成的结果作为参数来生成下一个, 以获得拥有多种功能的context, 这个设计还是很巧妙的:
类型名称作用方法Background返回一个emptyCtx实例TODO返回一个emptyCtx实例. 官方推荐是, 当不知道应该用哪个的时候, 临时使用TODOWithCancel在一个context的基础上, 生成一个可以取消的context. 两个context均可以执行取消的操作, 取决于哪个先发生WithDeadline在一个context基础上, 生成一个特定时间关闭的contextWithTimeout在一个context基础上, 生成一个特定时长关闭的contextWithValue在一个context基础上, 生成一个拥有指定k-v的context变量Canceled定义好的取消文案DeadlineExceeded定义好的取消文案. 时间到了
最后
最后, 在查看了Context内容之后, 有些个人的小疑问.
1. Context接口设计的过于臃肿
其实, Context并不需要保存k-v, 应用程序总是可以通过自己的方式将上下文在多个协程之间共享的.
并且, Deadline和Done方法是否有些臃肿? 其实子协程仅仅需要知道是否退出即可, 甚至于我觉得Context只需要实现这样一个方法就可以了:
IsCancel() (cancel bool, e err)
十分简洁, 只需要告诉子协程是否退出及原因不就可以了么?
当然, 也可能官方是出于其他我没有想到的原因考虑.
2. parent只能通知子协程退出, 但子协程什么时候退出parent是不知道的
如题, parent通过Context通知子协程退出后, 对于子协程是否退出是没有感知的. 现实中是否有这样的场景暂时没有想到, 不过应该会有吧. 原文链接: https://hujingnb.com/archives/825
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922433.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!