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

为什么 gorilla websocket 聊天示例没有发现使用 sync.RWMutex

为什么 gorilla websocket 聊天示例没有发现使用 sync.RWMutex

Go
弑天下 2021-11-08 18:26:29
在聊天示例中有一个名为 hub.go 的文件。https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go我对该文件进行了一些更改,它看起来像这样:type hub struct {    // Registered connections.    connections map[int64]*connection    sync.RWMutex    // Inbound messages from the connections.    broadcast chan []byte    // Register requests from the connections.    register chan *connection    // Unregister requests from connections.    unregister chan *connection}var wsHub = hub{    connections: make(map[int64]*connection),    broadcast:   make(chan []byte),    register:    make(chan *connection),    unregister:  make(chan *connection),}func (h *hub) init() {    for {        select {        case c := <-h.register:            h.Lock()            h.connections[c.userId] = c            h.Unlock()        case c := <-h.unregister:            h.RLock()            _, ok := h.connections[c.userId]            h.RUnlock()            if ok {                h.Lock()                delete(h.connections, c.userId)                h.Unlock()                close(c.send)            }        case m := <-h.broadcast:            for _, c := range h.connections {                select {                case c.send <- m:                default:                    close(c.send)                    delete(h.connections, c.userId)                }            }        }    }}我已将 sync.RWMutex 添加到集线器结构中,但我不确定这是否有必要。为什么它不包含在示例中?也许我错过了什么?锁定和解锁是不是太过分了?还有 init() 方法中的最后一种情况,我不确定如何锁定和解锁,因为它同时读取和写入。我应该同时使用 Rlock() 和 Lock() 吗?那会是什么样子?
查看完整描述

1 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

不需要互斥体,因为单个集线器 goroutine是唯一访问映射的 goroutine。


另一种方法是消除 Go 例程和通道,并用使用互斥锁的函数替换它们。


type hub struct {

  connections map[*connection]bool

  mu sync.Mutex

}


var h = hub{

   connections: make(map[*connection]bool),

}


func (h * hub) register(c *connection) {

  h.mu.Lock()

  h.connections[c] = true

}


func (h *hub) unregister(c *connection) {

  h.mu.Lock()

  if _, ok := h.connections[c]; ok {

     delete(h.connections, c)

     close(c.send)

  }

  h.mu.Unlock()

}


func (h * hub) broadcast(message []byte) {

  h.mu.Lock()

  for c := range h.connections {

    select {

    case c.send <- m:

    default:

      close(c.send)

      delete(h.connections, c)

    }

  }

  h.mu.Unlock()

}

保护close(c.send)和c.send <- m使用互斥锁很重要。这可以防止在关闭的通道上发送。


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 218 浏览
慕课专栏
更多

添加回答

举报

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