【发布时间】:2017-03-26 18:23:29
【问题描述】:
我有一个名为Hub 的结构,它有一个Run() 方法,它在它自己的goroutine 中执行。此方法按顺序处理传入消息。消息同时从多个生产者(单独的 goroutines)到达。当然,我使用channel 来完成这项任务。但现在我想将Hub 隐藏在interface 后面,以便能够从其实现中进行选择。因此,将channel 用作简单的Hub 字段是不合适的。
package main
import "fmt"
import "time"
type Hub struct {
msgs chan string
}
func (h *Hub) Run() {
for {
msg, hasMore := <- h.msgs
if !hasMore {
return
}
fmt.Println("hub: msg received", msg)
}
}
func (h *Hub) SendMsg(msg string) {
h.msgs <- msg
}
func send(h *Hub, prefix string) {
for i := 0; i < 5; i++ {
fmt.Println("main: sending msg")
h.SendMsg(fmt.Sprintf("%s %d", prefix, i))
}
}
func main() {
h := &Hub{make(chan string)}
go h.Run()
for i := 0; i < 10; i++ {
go send(h, fmt.Sprintf("msg sender #%d", i))
}
time.Sleep(time.Second)
}
所以我引入了Hub.SendMsg(msg string) 函数,它只调用h.msgs <- msg,我可以将它添加到HubInterface。作为Go-newbie,我想知道,从并发的角度来看它是否安全?如果是这样 - 这是Go 中的常用方法吗?
游乐场here.
【问题讨论】:
-
是的。我不知道该怎么回答,因为我不确定什么会让你相信它可能不安全。
-
@JimB,实际上,在思考了它在后台是如何工作的之后,我意识到答案是非常明显的,因为写入通道是线程安全的。
-
单个通道可用于发送语句、接收操作以及由任意数量的 goroutine 调用内置函数 cap 和 len,而无需进一步同步。 ,见If I am using channels properly should I need to use mutexes?
标签: go concurrency channel goroutine