在socket.go文件中的SimpleQuery函数中,有一个名为mutex的本地互斥锁。

huangapple go评论154阅读模式
英文:

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

他们正在将SimpleQueryreplyFunc进行同步。

  • wait用于等待replyFunc真正完成。
  • change用于锁定对replyDatareplyErr的访问。
英文:

They are synching the SimpleQuery with the replyFunc.

  • wait is used to wait until replyFunc is really done.
  • change is used to lock access to replyData and replyErr.

答案2

得分: 1

互斥锁用于保护数据结构,它们都在传递给replyFunc回调函数的闭包中被捕获。

wait互斥锁会阻塞,直到回调函数返回,而change互斥锁则保护replyDatareplyErr的值。

添加这些互斥锁的提交只是说:

> 使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.

huangapple
  • 本文由 发表于 2017年8月14日 20:59:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/45675092.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定