我不喜欢Go的一个方面是频道接收也会从频道中删除数据。这只允许两个goroutine相互通信,即使有两种或多种goroutine应该能够相互通信的情况。
我知道我可以创建一个通道数组并且每个goroutine都有通道,但是将数据从一个goroutine移动到所有其他goroutine的数据就是ram上的数据要多于将一个数据副本移动到所有goroutine。
考虑一个案例,当我有数千个客户端连接到服务器,我希望一个人只向其中一半发送消息,即接收该消息的五百个goroutines。如果消息是512字节,则在RAM移动中变为250千字节的数据,即使如果通道不会在接收时移除数据,也可以仅移动相同的数据一次。
所以我问是否有一些简单的方法可以做到这一点,还是我必须使用同步包中的互斥锁?虽然请告诉我,如果我计算错误并且频道不复制数据,因为在这种情况下我可以管理频道阵列。
答案 0 :(得分:2)
阅读这篇文章:
这是对通过goroutines进行频道广播的不同方式的分析,其中一个特别有趣:
type Broadcaster struct {
Listenc chan chan (chan broadcast);
Sendc chan<- interface{};
}
这种方法被作者称为“链接频道”(与链接列表密切相关)。
告诉我,如果我计算错误并且频道不复制数据,因为在这种情况下我可以管理频道数组。
你没错。正如@Jsor所建议的那样 - 如果您害怕复制开销并且用例允许它,您可以只传递指针。
答案 1 :(得分:1)
我通常做这样的事情:
type Message struct {
text string
address string
...
}
type Server {
dropbox chan Message
clients []*Conn
...
}
type Conn {
inbox chan *Message
...
}
每个客户端,通过读/写操作程序,将“消息”放入“dropbox”。服务器从“dropbox”中提取消息,并根据“地址”确定将消息发送到哪些客户端。
在服务器中,“客户”甚至可以是地图。这实际上取决于您希望如何路由消息:特定客户端,组等。
你可以使用chan chan T
做一些聪明的事情,但是如果你想进行智能路由而不是盲目广播,你真的需要一些方法将消息映射到客户端。
在这种情况下,您不需要互斥锁。在某些情况下,互斥锁是最好的,但在这种情况下,通道更容易。