为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕雪6442864 2022-06-01 17:27:25
我有一个使用 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) }
查看完整描述

2 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

因为监听器只需要写,而发送者只需要读——这是使用通道进行通信的一个很好的例子。流程如下所示:

  1. 侦听器会将新客户端发布到频道。

  2. 发件人将接收新客户端并将更新其本地客户端切片。

这样会更干净、更安全——因为监听器将无法“意外”读取,而发送者将无法“意外”写入。侦听器也可以关闭通道以向发送者指示它已完成。


查看完整回答
反对 回复 2022-06-01
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

切片看起来适合该场景,但需要一个互斥锁来防止并发读取和写入切片。


让我们将 slice 和 mutex 捆绑在一个结构中,并为这两个操作添加方法:添加和枚举。


type clients struct {

    mu     sync.Mutex

    values []*net.UDPAddr

}


// add adds a new client

func (c *clients) add(value *net.UDPAddr) {

    c.mu.Lock()

    c.values = append(c.values, value)

    c.mu.Unlock()

}


// do calls fn for each client

func (c *clients) do(fn func(*net.UDPAddr) error) error {

    c.mu.Lock()

    defer c.mu.Unlock()

    for _, value := range c.values {

        if err := fn(value); err != nil {

            return err

        }

    }

    return nil

}

像这样使用它:


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

    for {

        clients.add(otherAddr)

    }

}


func sender(messages chan clientMessage, clients *clients) {


    for {

        message := <-messages

        clients.do(func(client *net.UDPAddr) error {

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

            return nil

        })

    }

}


func main() {

    var clients clients

    go listener(s, &clients, messageCh)

    go sender(messageCh, &clients)

}


查看完整回答
反对 回复 2022-06-01
  • 2 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信