登录
首页 >  Golang >  Go问答

在 if-else 外部锁定某些数据并在 if-else 内部解锁是一个好习惯吗?

来源:stackoverflow

时间:2024-02-12 13:27:22 222浏览 收藏

从现在开始,努力学习吧!本文《在 if-else 外部锁定某些数据并在 if-else 内部解锁是一个好习惯吗?》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

问题内容

当我测试 rf.state == candidate 时,可能会发生竞争。所以我在此之前锁定了 struct rf 。我想确保 rf.state 完全出现在 if 条件测试中,以便我可以使用其最新值。

...
func (rf *raft) runelection() {
    rf.mu.lock()
    rf.currentterm += 1
    rf.votedfor = rf.me
    rf.votes = 1
    rf.mu.unlock()

    for server := range rf.peers {
        rf.mu.lock()
        if server != rf.me && rf.state == candidate {
            rf.mu.unlock()
            go rf.sendrequestvote(server)
        } else {
            rf.mu.unlock()
        }
    }
}

...

在类似情况下是否有其他惯用的方法来锁定数据(if-else、switch...)?

编辑: 这是我的一些其他代码。

...
rf.mu.Lock()
switch rf.state {
case follower:
        rf.mu.Unlock()

        select {
        case <-rf.chanAppends:
        case <-rf.chanGrantVotes:
        case <-time.After(time.Duration(500+rand.Intn(1000)) * time.Millisecond):
                rf.mu.Lock()
                rf.state = candidate
                rf.mu.Unlock()
        }
case candidate:
        rf.mu.Unlock()
        ...
case leader:
        rf.mu.Unlock()
        ...

要在 switch 上使用当前的 rf.state,我必须在外部锁定并在内部解锁。令我困扰的是,对于每种情况,我都必须解锁每种情况(使代码不太干净和可读?)。并且有一些阻塞(例如 time.after(...) )会在每个案例中创建一个计时器,所以我看不到使用 defer 来帮助我的方法。我想如果我不想改变这个 switch 的逻辑结构,我必须做出一些权衡?


正确答案


虽然您的代码看起来不错,但您始终可以将各个部分提取到它们自己的函数中以使用 defer

func (rf *Raft) runElection() {
    // ...

    for server := range rf.peers {
        tryVote(rf, server)
    }
}

func tryVote(rf *Raft, server xxx) {
    rf.mu.Lock()
    defer rf.mu.Unlock()
    if server != rf.me && rf.state == candidate {
        go rf.sendRequestVote(server)
    }
}

当您的代码变得更加复杂并且您希望绝对确保从某些代码部分返回后互斥锁会被解锁时,这尤其有用。

本篇关于《在 if-else 外部锁定某些数据并在 if-else 内部解锁是一个好习惯吗?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>