【发布时间】:2017-07-28 19:05:14
【问题描述】:
我正在用 Go 编写一个 CMS,并且有一个会话类型(用户 ID、要呈现的页面内容等)。理想情况下,我希望该类型是一个全局变量,因此我不必通过所有嵌套函数传播它,但是拥有这样的全局变量显然意味着每个新会话都会覆盖它的前任,这不必要说,将是史诗般的失败。
一些语言提供了一种在线程中保存全局变量的方法(即,该全局变量的值在该线程中被沙盒化)。虽然我知道 Goroutine 不是线程化的,但我只是想知道是否有类似的方法可供我使用,或者我是否必须通过各种嵌套例程向下传递会话类型的本地指针。
我猜频道不会这样做?据我所知(如果我在这里错了,请纠正我),但它们基本上只是一种共享全局变量的安全方式?
编辑:我忘记了这个问题!无论如何,任何好奇的人的更新。这个问题是我刚接触 Go 时写的,CMS 基本上是我的第一个项目。我来自熟悉 POSIX 线程的 C 背景,但我很快意识到更好的方法是在模式功能设计中编写代码,会话对象作为函数参数中的指针向下传递。这为我提供了我所追求的上下文相关的本地范围,同时也最大限度地减少了我正在复制的数据量。然而,作为一个有 7 年历史的项目,也是我开始向 Go 过渡的一个项目,可以公平地说,该项目无论如何都可以进行重大重写,因为犯了很多错误。不过,这是另一天的担忧 - 目前它有效,而且我还有足够多的其他项目在进行中。
【问题讨论】:
-
看起来没有 threadlocal 功能,因此您必须传递上下文对象:groups.google.com/forum/#!topic/golang-nuts/_Vv7Bzn8yH4 尽管您可以使用全局哈希表和goroutine 的内部 id:groups.google.com/forum/#!topic/golang-nuts/Iyg3lKHV_lQ
-
我确实考虑过使用哈希表,但如果管理不当,这是一种创建内存泄漏的简单方法,所以如果涉及到,我宁愿向下传递本地指针,因为 GC 应该管理为我休息。 runtime 看起来很有趣。谢谢。
-
这是一个有趣的问题,因为在现实世界中,您的应用程序的很大一部分可能正在使用安全、事务,因此我可以看到这是多么乏味。在 FP 语言中,通常使用单子和词法闭包。也许 Go 有某种类似 monad 的能力?
-
频道不是“只是一种共享全局变量的方式”。确实,通道是在 goroutine 之间共享数据的首选方式(moto 是“通过通信共享,不要通过共享进行通信”)。但首先,它是在大多数并发上下文中正确实现同步的基本技术,受 CSP en.wikipedia.org/wiki/Communicating_sequential_processes 的启发。请记住,goroutine 在写入或读取时相互等待(阻塞)。
-
我说的是“安全共享变量的方式”,“安全”是您遗憾地漏掉的关键词。在多线程例程中锁定变量并不是一个新概念,也不是 Go 独有的。在我编写的多线程应用程序的所有其他语言中,存在锁定变量以防止在处理异步/并行进程时出现竞争条件。虽然我承认 Go 已经采用了这个概念并对其进行了更多的发展,而且我也承认我的解释被大大简化了,但你所描述的只是对我的总结的更冗长的描述。跨度>
标签: go concurrency