在Go中管理多个通道

在Go中管理多个通道,go,channel,Go,Channel,我是一个新手&我正在编写一个简单的web应用程序。其基本思想是: goroutine#1是HTTP服务器 goroutine#2是一个管理应用程序状态的函数。它需要周期性地轮询一些硬件的值,因此它需要在自己的线程中运行 当用户发出HTTP请求时,服务器将从状态goroutine请求更新的信息,然后向客户端返回HTML页面 除了一件事之外,这一切都运行得非常好:目前服务器发送了六个不同的可能信号,并从状态线程返回,同时有一个请求和一个响应通道,总共有12个通道(我将添加至少一个或两个信号)。也许可

我是一个新手&我正在编写一个简单的web应用程序。其基本思想是:

goroutine#1是HTTP服务器

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

当用户发出HTTP请求时,服务器将从状态goroutine请求更新的信息,然后向客户端返回HTML页面

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

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

它看起来像这样:

main.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)
所以,有几个问题:

  • 是否需要有单独的请求和响应通道?考虑到请求和响应是不同的类型,我看不到一种明显的方法可以在两个方向上使用同一个通道(这不是黑客行为)

  • 我曾考虑将所有通道放入一个可以传递给所有goroutine的结构中,但我不确定这是否会有任何真正的好处——这似乎比我现在所做的要清楚得多

  • 什么是前进之路™ 为什么要这样做

  • 更新

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


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

    我根本不会使用频道


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

    go是指完成任务,如果可行,就这样;-)。克斯特亚的回答很好。不要过度设计和强迫你的程序用频道和Goroutine做所有事情,认为这是可行的方法。用互斥锁保护全球国家没有错;通常这是完成事情最简单、直接和有效的方法。如果你需要一个goroutine来监视硬件更新,那么就让它来更新全局状态。如果你有一个复制程序,我建议你提交一个关于Lock()调用无法解除阻塞的bug。