猿问

在不同的 go 例程中读取/写入记录集 - 使用什么数据结构

我有一个使用 2 个 go 例程的聊天应用程序。我想在一个线程中的列表中添加/删除记录,并从另一个线程中读取相同的列表。


由于我是 Go 的新手,我对应该使用什么数据结构有点困惑。我想到了切片,但不确定我是否以正确的方式使用它


func listener(addr *net.UDPAddr, clients *[] *net.UDPAddr, messages chan clientMessage) {


    for {

            *clients=append(*clients,otherAddr)     

    }

}


func sender(messages chan clientMessage,clients *[] *net.UDPAddr) {


  for {

    message :=<- messages

    for _,client := range *clients {

            fmt.Printf("Message %s sent to %s\n", message.message, client.String())


    }

  }

}



func main() {   

    var clients [] *net.UDPAddr

    go listener(s,&clients,messageCh)

    go sender(messageCh,&clients) 

}


慕雪6442864
浏览 100回答 2
2回答

叮当猫咪

因为监听器只需要写,而发送者只需要读——这是使用通道进行通信的一个很好的例子。流程如下所示:侦听器会将新客户端发布到频道。发件人将接收新客户端并将更新其本地客户端切片。这样会更干净、更安全——因为监听器将无法“意外”读取,而发送者将无法“意外”写入。侦听器也可以关闭通道以向发送者指示它已完成。

拉莫斯之舞

切片看起来适合该场景,但需要一个互斥锁来防止并发读取和写入切片。让我们将 slice 和 mutex 捆绑在一个结构中,并为这两个操作添加方法:添加和枚举。type clients struct {&nbsp; &nbsp; mu&nbsp; &nbsp; &nbsp;sync.Mutex&nbsp; &nbsp; values []*net.UDPAddr}// add adds a new clientfunc (c *clients) add(value *net.UDPAddr) {&nbsp; &nbsp; c.mu.Lock()&nbsp; &nbsp; c.values = append(c.values, value)&nbsp; &nbsp; c.mu.Unlock()}// do calls fn for each clientfunc (c *clients) do(fn func(*net.UDPAddr) error) error {&nbsp; &nbsp; c.mu.Lock()&nbsp; &nbsp; defer c.mu.Unlock()&nbsp; &nbsp; for _, value := range c.values {&nbsp; &nbsp; &nbsp; &nbsp; if err := fn(value); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return nil}像这样使用它:func listener(addr *net.UDPAddr, clients *clients, messages chan clientMessage) {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; clients.add(otherAddr)&nbsp; &nbsp; }}func sender(messages chan clientMessage, clients *clients) {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; message := <-messages&nbsp; &nbsp; &nbsp; &nbsp; clients.do(func(client *net.UDPAddr) error {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Message %s sent to %s\n", message.message, client.String())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; var clients clients&nbsp; &nbsp; go listener(s, &clients, messageCh)&nbsp; &nbsp; go sender(messageCh, &clients)}
随时随地看视频慕课网APP

相关分类

Go
我要回答