没有 goroutines 覆盖的 Go lang 全局变量

标签 go concurrency

我正在用 Go 编写一个 CMS,并且有一个 session 类型(用户 ID、要呈现的页面内容等)。理想情况下,我希望该类型是一个全局变量,这样我就不必通过所有嵌套函数传播它,但是拥有一个这样的全局变量显然意味着每个新 session 都会覆盖它的前任,这不必要地说,将是一个史诗般的失败。

一些语言提供了一种在线程中拥有全局变量的方法,这些全局变量被保存在该线程中(即,该全局变量的值在该线程中被沙盒化)。虽然我知道 Goroutines 不是线程,但我只是想知道是否有类似的方法可供我使用,或者我是否必须通过各种嵌套例程向下传递我的 session 类型的本地指针。

我猜 channel 不会这样做?据我所知(如果我在这里错了请纠正我),但它们基本上只是一种共享全局变量的安全方式?

编辑:我忘记了这个问题!无论如何,为任何好奇的人提供更新。这个问题是我刚接触 Go 的时候写回来的,CMS 基本上是我的第一个项目。我来自熟悉 POSIX 线程的 C 背景,但我很快意识到一种更好的方法是在模式功能设计中编写代码, session 对象作为函数参数中的指针传递。这为我提供了我所追求的上下文相关的本地范围,同时也最大限度地减少了我正在复制的数据量。然而,作为一个有 7 年历史的项目,并且是在我开始过渡到 Go 的时候,可以公平地说,这个项目无论如何都可以进行重大重写,因为它犯了很多错误。不过,这是另一天的问题 - 目前它有效,我还有足够多的其他项目在进行中。

最佳答案

你会想要使用类似Context的东西:

http://blog.golang.org/context

基本上,该模式是为您想做的每个独特的事情创建一个Context。 (在你的情况下是一个网络请求。)使用 context.WithValue 在上下文中嵌入多个变量。然后总是将它作为第一个参数传递给在其他 goroutine 中做进一步工作的其他方法。

从上下文中获取您需要的变量是从任何 goroutine 中调用 context.Value 的问题。从上面的链接:

A Context is safe for simultaneous use by multiple goroutines. Code can pass a single Context to any number of goroutines and cancel that Context to signal all of them.

我有一个实现,其中我明确地将变量作为方法参数发送,我发现使用上下文嵌入这些变量可以显着清理我的代码。

使用 Context 也有帮助,因为它提供了使用 channel 、select 和称为“完成 channel ”的概念来结束长时间运行的任务的方法。请参阅这篇文章以获得出色的基本审查和实现:

http://blog.golang.org/pipelines

我建议先阅读管道文章,了解如何管理 goroutine 之间的通信,然后再阅读上下文文章,更好地了解如何升级并开始嵌入变量以传递。

祝你好运!

关于没有 goroutines 覆盖的 Go lang 全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15768970/

相关文章:

api View 中的 golang 后台工作进程

google-app-engine - 谷歌云存储 : Error 401: Invalid Credentials

go - 使用入口部署 Rest + gRPC 服务器部署到 k8s

sockets - 使用 select 进行非阻塞读取

并行部分任务的 Java 并发模式

concurrency - CUDA 原子操作和并发内核启动

string - Golang将字符串转换为io.Writer?

java - 原子比较和交换是否可以在看不到惰性写入的情况下覆盖它?

c# - System.Timers.Timer 奇怪的行为?被阻止的事件不会被堆叠

rest - 如何从 goREST POST 端点返回消息?