【问题标题】:Managing multiple channels in Go在 Go 中管理多个频道
【发布时间】:2016-03-02 02:54:21
【问题描述】:

我是 Go 新手,我正在编写一个简单的 Web 应用程序。基本思路是这样的:

goroutine #1 是 HTTP 服务器

goroutine #2 是一个管理应用程序状态的函数。它需要定期轮询一些硬件的值,所以它需要在自己的线程中运行。

当用户发出 HTTP 请求时,服务器会向 state goroutine 请求更新的信息,然后返回一个 HTML 页面给客户端。

这一切都很好,除了一件事:目前有六种不同的可能信号由服务器发送并从状态线程返回,包括请求和响应通道,总共 12 个通道(我m 将添加至少一个或两个以上的信号)。可以合并一些信号,但其中许多是不同的类型。

正如我所说,它有效,但它变得相当丑陋。

看起来像这样:

ma​​in.go 包含用于实例化通道的声明:

// a shutdown signal
shutdown := make(chan bool)

// request the current state of a sensor
sensorRequest := make(chan string)
sensorResponse := make(chan Sensor)

// request the current state of ALL sensors
sensorListRequest := make(chan bool)
sensorListResponse := make(chan []Sensor)

// request the current state of the application (active or inactive)
statusRequest := make(chan bool)
statusResponse := make(chan bool)

// and a few more...

// start the "state manager" goroutine
go ManageState(shutdown, sensorRequest, sensorResponse, sensorListRequest, sensorListResponse, statusRequest, statusResponse)

// start the "HTTP server" goroutine
go ManageHTTP(shutdown, sensorRequest, sensorResponse, sensorListRequest, sensorListResponse, statusRequest, statusResponse)

所以,有几个问题:

  1. 是否需要有单独的请求和响应通道?鉴于请求和响应是不同的类型,我看不到在两个方向上使用相同通道的明显方法(这不是 hacky)。

  2. 我考虑将所有通道放入一个可以传递给所有 goroutine 的结构中,但我不确定这会带来什么真正的好处 - 它似乎并不比我更清楚现在做。

  3. 这样做的Go方式™是什么?

更新

感谢@kostya 和@Aedolon 建议使用sync.Mutex 锁定/解锁的全局状态。这实际上是我的第一种方法,但我遇到了一个严重的问题:我的 Mutex Lock() 调用在释放锁时随机无法解锁。此代码将在 Raspberry Pi 上运行,我怀疑某处存在错误(在我用来读取硬件状态的包中或 Go ARM 二进制文件中)。但在花了很多时间试图追踪问题之后,我决定尝试不同的方法。

无论如何,在阅读(多次)我应该“不要通过共享内存进行通信;而是通过通信来共享内存”(The Go Blog)之后,我决定尝试以这种方式实现它。现在我这样做了,我发现我喜欢这种方法:-)

【问题讨论】:

  • Go 是关于完成工作的,如果它有效,它就是 Go 的方式;-)。
  • kostya 的回答很好。不要过度设计和强迫你的程序用通道和 goroutine 做所有事情,认为这就是 Go Way。用互斥锁保护全局状态并没有错。这通常是完成工作的最简单、直接和有效的方法。如果您需要一个监视硬件更新的 goroutine,那么就拥有它并让它更新全局状态。
  • 如果你有复制器,我建议提交一个关于 Lock() 调用无法解除阻塞的错误。

标签: go channel


【解决方案1】:

我根本不会为此使用频道。

您可以从多个 go-routines 的同一变量中更新和读取共享状态,并使用 sync.RWMutex 进行同步。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2019-10-08
    • 1970-01-01
    • 2021-12-03
    • 2011-03-04
    • 2016-05-30
    • 2017-05-12
    相关资源
    最近更新 更多