У меня есть структура, называемая 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
-новичок, интересно, безопасно ли оно с точки зрения параллелизма? И если да - это общий подход в Go
?
Детская площадка here.
Да. Я не уверен, как еще ответить, потому что я не уверен, что привело бы вас к тому, что это может быть опасно. – JimB
@JimB, на самом деле, подумав, как это работает под капотом, я понял, что ответ довольно очевиден, поскольку запись на канал является потокобезопасной. –
_A один канал может использоваться в операторах отправки, приемах и вызовах встроенных функций cap и len любым количеством goroutines без дальнейшей синхронизации. Дополнительная информация приведена в разделе [Если я правильно использую каналы, если мне нужно использовать мьютексы?] (http://stackoverflow.com/questions/34039229/if-i-am-using-channels-properly-should-i-need-to-use-mutexes) – icza