2017-08-14 92 views
1

我试着读取mgo的代码,并且socket.go中的函数SimpleQuery让我困惑。在这个功能中,有两个地方互斥: https://github.com/go-mgo/mgo/blob/v2-unstable/socket.go本地互斥在SimpleQuery中的socket.go

func (socket *mongoSocket) SimpleQuery(op *queryOp) (data []byte, err error) { 
    var wait, change sync.Mutex 
    var replyDone bool 
    var replyData []byte 
    var replyErr error 
    wait.Lock() 
    op.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) { 
     change.Lock() 
     if !replyDone { 
      replyDone = true 
      replyErr = err 
      if err == nil { 
       replyData = docData 
      } 
     } 
     change.Unlock() 
     wait.Unlock() 
    } 
    err = socket.Query(op) 
    if err != nil { 
     return nil, err 
    } 
    wait.Lock() 
    change.Lock() 
    data = replyData 
    err = replyErr 
    change.Unlock() 
    return data, err 
} 

至于我的理解,对于每一个电话,就会有一个新的地方互斥体,因此,它实际上是保护什么,他们为什么把互斥吗?

回答

1

的互斥被保护的数据结构,它们都在给予replyFunc回调封闭捕获。

wait互斥量阻塞,直到回调返回,并且change互斥量保护replyDatareplyErr值。

的承诺是增加那些只说:

让SimpleQuery比赛的安全,无论什么样的服务器呢。

因此,这可能是对某些意外或遗留行为的额外保护,这就是为什么它使用多个互斥锁而不是单个基元来同步操作。

2

他们正在同步SimpleQueryreplyFunc

  • wait用于等到replyFunc是真正完成。
  • change用于锁定对replyDatareplyErr的访问。