去两个以上的goroutines

时间:2013-08-02 07:42:58

标签: go

我不喜欢Go的一个方面是频道接收也会从频道中删除数据。这只允许两个goroutine相互通信,即使有两种或多种goroutine应该能够相互通信的情况。

我知道我可以创建一个通道数组并且每个goroutine都有通道,但是将数据从一个goroutine移动到所有其他goroutine的数据就是ram上的数据要多于将一个数据副本移动到所有goroutine。

考虑一个案例,当我有数千个客户端连接到服务器,我希望一个人只向其中一半发送消息,即接收该消息的五百个goroutines。如果消息是512字节,则在RAM移动中变为250千字节的数据,即使如果通道不会在接收时移除数据,也可以仅移动相同的数据一次。

所以我问是否有一些简单的方法可以做到这一点,还是我必须使用同步包中的互斥锁?虽然请告诉我,如果我计算错误并且频道不复制数据,因为在这种情况下我可以管理频道阵列。

2 个答案:

答案 0 :(得分:2)

阅读这篇文章:

http://rogpeppe.wordpress.com/2009/12/01/concurrent-idioms-1-broadcasting-values-in-go-with-linked-channels/

这是对通过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做一些聪明的事情,但是如果你想进行智能路由而不是盲目广播,你真的需要一些方法将消息映射到客户端。

在这种情况下,您不需要互斥锁。在某些情况下,互斥锁是最好的,但在这种情况下,通道更容易。