英文:
local mutex in SimpleQuery in socket.go
问题
我尝试阅读mgo的代码,并且在socket.go文件中的SimpleQuery函数让我感到困惑。在这个函数中,有两个本地的互斥锁:
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
}
据我理解,对于每次调用,都会有一个新的本地互斥锁,所以它实际上没有保护任何东西,为什么他们在这里放置了互斥锁呢?
英文:
I tried to read code of mgo, and the function SimpleQuery in socket.go confused me. In this function, there are two local mutex:
https://github.com/go-mgo/mgo/blob/v2-unstable/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
}
As my understanding, for each call, there will be a new local mutex, so, it's actually protecting anything, why they put the mutex here?
答案1
得分: 2
他们正在将SimpleQuery与replyFunc进行同步。
wait用于等待replyFunc真正完成。change用于锁定对replyData和replyErr的访问。
英文:
They are synching the SimpleQuery with the replyFunc.
waitis used to wait untilreplyFuncis really done.changeis used to lock access toreplyDataandreplyErr.
答案2
得分: 1
互斥锁用于保护数据结构,它们都在传递给replyFunc回调函数的闭包中被捕获。
wait互斥锁会阻塞,直到回调函数返回,而change互斥锁则保护replyData和replyErr的值。
添加这些互斥锁的提交只是说:
> 使SimpleQuery在服务器执行的情况下具有竞争安全性。
因此,这可能是对一些意外或遗留行为的额外保护,这就是为什么它使用多个互斥锁而不是单个原语来同步操作的原因。
英文:
The mutexes are protecting data structures, they are both captured in the closure given to the replyFunc callback.
The wait mutex blocks until the callback returns, and the change mutex protects the replyData and replyErr values.
The commit that added those only says:
> Make SimpleQuery race safe, irrespective of what the server does.
So this may be extra protection against some unintended or legacy behavior, which is why it's using multiple mutexes rather than a single primitive to synchronize the operation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论