通常,当使用多个goroutines编写并发程序时,这些goroutines需要访问客户端,例如编写REST,其中每个HTTP处理程序需要使用单个初始化的Redis客户端来读取和写入Redis实例。
我要么有一个具有互斥锁的客户端实例,所以只有一个goroutine可以在任何时候使用它,要么有一个客户端goroutine,其他的goroutine可以通过一个通道请求读取。这两种方式都有效,但我想知道哪一种更地道呢?谢谢你的帮忙
发布于 2015-04-22 13:47:57
如果您只有一个客户端,并且只执行简单的操作,请使用互斥对象。它通常简单易懂,不像一组通道和select语句的goroutine。确保封装线程安全,以免给API用户带来锁负担。
比较:
var (
mutex sync.Mutex
resource = 0
)
func Inc() int {
mutex.Lock()
defer mutex.Unlock()
resource++
return resource
}通过以下方式:
var requests = make(chan chan int)
func init() {
go func() {
resource := 0
for {
response := <- requests
resource++
response <- resource
}
}()
}
func Inc() int {
response := make(chan int)
requests <- response
return <-response
}前者显然更简洁,更易于维护。特别是在资源不是全局的情况下,通道方法还需要对goroutines进行手动管理,因为goroutines不是垃圾收集的(参见how to stop a goroutine)。
如果您不介意拥有多个客户端,请使用一个客户池。go-redis支持开箱即用。池本身是线程安全的,可以用于获取空闲连接之一。
https://stackoverflow.com/questions/29799517
复制相似问题