为了账号安全,请及时绑定邮箱和手机立即绑定

惯用的 Golang 协程

惯用的 Golang 协程

Go
慕田峪7331174 2021-09-13 16:38:15
在 Go 中,如果我们有一个类型的方法启动一些循环机制(轮询 A 并永远执行 B),最好将其表示为:// Run does stuff, you probably want to run this as a goroutinefunc (t Type) Run() {    // Do long-running stuff}并记录这可能希望作为 goroutine 启动(并让调用者处理它)或者向调用者隐藏它:// Run does stuff concurrentlyfunc (t Type) Run() {   go DoRunStuff()}我是 Go 的新手,不确定约定是否让调用者前缀为“go”,或者在代码设计为异步运行时为他们做这件事。我目前的观点是我们应该记录并给调用者一个选择。我的想法是,在 Go 中,并发实际上并不是公开接口的一部分,而是使用它的一个属性。这是正确的吗?
查看完整描述

3 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

在我开始为我想要并发的 Web 服务编写适配器之前,我对此有您的看法。我有一个必须启动的 go 例程来解析从 web 调用返回到通道的结果。如果不将其用作 go 例程,则绝对不会出现此 API 可以工作的情况。

然后我开始查看像 net/http 这样的包。该包中有强制并发。在接口级别记录它应该能够同时使用,但是默认实现会自动使用 go 例程。

因为 Go 的标准库通常在它自己的包中触发 go 例程,我认为如果你的包或 API 有保证,你可以自己处理它们。


查看完整回答
反对 回复 2021-09-13
?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

我目前的观点是我们应该记录并给调用者一个选择。

我倾向于同意你的看法。

由于 Go 使并发运行代码变得如此容易,因此您应该尽量避免 API 中的并发(这会迫使客户端并发使用它)。相反,创建一个同步 API,然后客户端可以选择同步或并发运行它。


特别是幻灯片 26,显示的代码更像您的第一个示例。

我会将该net/http包视为一个例外,因为在这种情况下,并发几乎是强制性的。如果包没有在内部使用并发,客户端代码几乎肯定必须使用。例如,http.Client(据我所知)不会启动任何 goroutine。只有服务器这样做。

在大多数情况下,无论哪种方式,它都将是调用者的一行代码:

go Run() 或者 StartGoroutine()

同步 API 并不难同时使用,并为调用者提供更多选择。


查看完整回答
反对 回复 2021-09-13
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

没有“正确”的答案,因为情况不同。

显然,在某些情况下,API 可能包含实用程序、简单算法、数据集合等,如果打包为 goroutines 会看起来很奇怪。

相反,在某些情况下,自然会期望“幕后”并发,例如丰富的 IO 库(http 服务器就是一个明显的例子)。

对于更极端的情况,请考虑您要生成即插即用并发服务库。这样的 API 由模块组成,每个模块都通过通道具有详细描述的接口。显然,在这种情况下,它不可避免地会涉及作为 API 一部分的 goroutine。

一个线索很可能是函数参数中是否存在通道。但我希望清楚地记录两种方式的预期结果。


查看完整回答
反对 回复 2021-09-13
  • 3 回答
  • 0 关注
  • 193 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信