英文:
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
.
wait
is used to wait untilreplyFunc
is really done.change
is used to lock access toreplyData
andreplyErr
.
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论