最近,当意识到系统的分布式日志和交易管理时,在寻求SO所谓的全球独特的Goroutine ID之后,它决定简单地使用上下文机制来实现基本思想。
上下文是Golang正式定义的软件包。它定义了上下文类型,其中包含截止日期/doin/err方法,并且成员变量的成员变量值绑定到上下文的值如下:特定定义如下:
它可以从字面上理解为上下文,以及更熟悉的过程/线程在线文本,关于Golang的上下文,一词总结:Goroutine相关的环境snapshotdiverent goroutine请求,因为在Golang Severs中,每个请求都在单个Goroutine中完成。
最近,公司分析了GRPC源代码,原始文件生成的代码以及接口函数的第一个参数是CTX Context.Context Interface。公司中的许多同事都不了解该设计的起点是什么。实际上,她利用台风尼台风的优势,降落在深圳。
上下文通常被翻译为上下文,这是一个相对抽象的概念。在对公司技术的讨论中,经常提到上下文。通常,它被理解为程序单元的运行状态。上下层的本质在上下传输,内容将传递到底部。在GO语言中,程序单元指的是Goroutine。
在执行每个Goroutine之前,您必须首先知道程序的当前执行状态,并通常将这些执行状态封装在上下文变量中,并将其传递给goroutine to decordectect.Standard方法。在网络编程下,在接收网络请求请求和处理请求时,我们可能需要打开不同的goroutine,以获取数据和逻辑处理,即将在多个goroutine中处理的请求请求。这些goroutine willmay需要分享有关请求的一些信息;同时,当请求被取消或加班时,本请求创建的所有goroutine也应结束。
注意:对Goroutine的理解可以在这里移动。
因为在Golang Severs中,每个请求都在一个Goroutine中完成,并且将在单个Goroutine(可能称为A)场景中提供其他服务的请求,将涉及多个Goroutine之间的调用。如果您一时要求取消其他服务,则需要作为当前的Goroutine B退出,然后该系统可以回收B. B.的资源,即,一个请求通常包含多个Goroutine,并且这些Goroutine通常具有相互作用。
因此,如何有效地将这些goroutine作为一个问题(主要是由于退出通知和元数据传输问题),Google解决方案是上下文机制,而彼此呼叫的Goroutine则通过传递上下文变量保持联系,并保持联系。实施详细信息,有效控制每个Goroutine的操作。
这样,您可以通过传递上下文来跟踪Goroutine调用树,并在这些呼叫树之间传递通知和元数据。尽管Goroutine是平行的,并且没有继承关系,但上下文旨在包括父亲的关系。这种方式可以更好地描述Goroutine调用之间的树类关系。
生成上下文有两种主要方法:
要创建上下文树,首先,创建根节点
此上下文通常由收到请求的第一个Goroutine创建。它不能取消,没有价值,也没有到期时间。它通常作为请求的顶层存在。
使用根节点,下一步是创建一个后代节点。为了很好地控制后代节点节点,上下文软件包提供的创建方法是第二个返回值(Cancelfunc),它等同于钩子,在gor仪上执行过程的子女,您可以触发钩子以实现目的控件子登录(通常取消它,也就是说,让它停止)。然后与上下文提供的完成方法合作,孩子Goroutine可以检查它是否是父节点取消:
注意:父节点上下文可以通过调用取消方法来主动调用子节点上下文,而子节点上下文只能被动地等待。同时,父节点上下文本身被取消(例如其上点节点取消),并且子级的所有子节点将自动自动自动取消。
有三种方法可以创建:
让我们看一个简单的适应示例,来自高级GO并发模式视频:
输出结果:
请注意,目前,未打印在DOSTH方法中完成的情况。
超时场景:
输出结果:
确实,通过引入上下文包,可以通过r效率控制所有Goroutine的取消。但是该解决方案还不够优雅。
一旦代码中的某个地方使用了上下文,传达上下文变量(通常是函数的第一个参数)将像病毒一样传播。对于Exipplecontext,将传递到任何数据库操作或日志记录所需的功能代码作为参数。也就是说,每个相关函数必须添加context.context参数,并且作为第一个参数,这完全是无关的代码是全部iNDVASIVE。
有关更多详细信息,请参阅:Michal Strba的上下文散布go2文章
关于Google Group的讨论可以搬到这里。
上下文机制的核心功能是传递Goroutine之间的取消信号,但其实现不完整。
取消可以细分为两种活动类型。通过传递上下文参数,调用Goroutine可以主动调用Goroutine。但是如何知道何时执行Goroutine。无法实现上下文机制的这一部分。实际上,实际上,有些场景,例如Goroutine,组装的数据必须等待其他Goroutine才能完成执行。这显然是不够的背景。您必须使用Sync.WaitGroup。
context.value等效于Goroutine的TLS(线程本地存储),但它不是静态类型的安全。任何结构变量都必须以字符串的形式存储。同时,所有上下文都定义了其中的变量,这很容易引起命名冲突。
上下文软件包可以通过构造树类关系的上下文来控制Goroutine下一层的控制,可以通过构建树类关系的上下文来控制Goroutine的先前层。为了处理请求操作,它需要使用上下文来控制goroutine层并传递一些变量以共享。
上下文对象的生存周期通常只是请求处理周期。也就是说,为请求创建上下文变量(这是上下文树结构的根);请求处理结束后,将撤销CTX变量并发布资源。
每次创建Goroutine时,要么将原始上下文传递给Goroutine,要么创建儿童上下文并传递给Goroutine。
上下文可以灵活地存储不同类型和不同数字的值,并使多个Goroutine安全地读取和写入值。
当通过父上下文对象创建ZI上下文对象时,您还可以获得ZI上下文的取消函数,以便父级上下文对象的创建环境已获得撤销Goroutine的权利,即ZI上下文将通过在。
在Goroutine传递给潜台词中,应监视子上下文的完成渠道。一旦频道关闭(即,该goroutine的执行被取消),则应主动终止有关当前请求信息处理,发布资源和返回的当前请求信息。