去没有goroutines覆盖的全局变量

时间:2013-04-02 16:10:47

标签: go concurrency

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

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

我猜测频道不会这样做?从我可以收集的内容(如果我在这里错了请纠正我),但它们基本上只是一种共享全局变量的安全方式?

编辑:我忘记了这个问题!无论如何,任何好奇的人的更新。这个问题是在我刚开始使用Go时回写的,而CMS基本上是我的第一个项目。我来自熟悉POSIX线程的C背景,但我很快意识到更好的方法是在模式功能设计中编写代码,将会话对象作为函数参数中的指针传递下来。这给了我我所关注的上下文敏感的本地范围,同时也最小化了我复制的数据量。然而,作为一个7岁的项目和一个刚开始转向Go的项目,可以说该项目无论如何都可以进行重大改写,因为存在很多错误。这是另一天的关注 - 目前它有效,而且我还有足够的其他项目。

3 个答案:

答案 0 :(得分:3)

您希望使用Context

之类的内容

http://blog.golang.org/context

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

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

  

Context对于多个goroutine同时使用是安全的。代码可以将单个Context传递给任意数量的goroutine,并取消Context以表示所有这些goroutine。

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

使用Context也有帮助,因为它提供了使用频道select以及称为“完成频道”的概念来结束长时间运行任务的方法。"请参阅此文章以获得一个很好的基本审核和实施:

http://blog.golang.org/pipelines

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

祝你好运!

答案 1 :(得分:1)

不要使用全局变量。使用Go goroutine-local变量。

  

go-routine Id..

     

已经存在goroutine-local变量:它们被称为函数   参数,函数返回值和局部变量。

     

拉​​斯

答案 2 :(得分:1)

如果您有多个用户,那么每个连接都不需要该信息吗?所以我认为每个连接用户都有一个结构。它是惯用的在设置worker goroutine时传递指向该结构的指针,或者将指针传递到通道上。