【问题标题】:Sync access for the same variable同一个变量的同步访问
【发布时间】:2019-07-07 19:05:03
【问题描述】:

我想确保对于给定值,我的更新函数一次只能由一个线程执行。

func update1(int id){
   ...
   makeUpdate(id)
   ...
}

func update2(int id){
   ...
   makeUpdate(id)
   ...
}

那么,我应该如何编写我的 makeUpdate() 函数,myUpdate 块对于给定的 id 值只执行一次?这意味着如果 update1 更新 id 为“15”的记录,update2 更新 id 为“20”的记录,则不应同步块访问。

【问题讨论】:

  • 这取决于记录是什么以及它们如何保存在内存中 - makeUpdate 的主体对于回答这个问题非常重要,但一般来说,在 Go 中,您的主要同步工具是通道和 @ 987654323@.
  • @Adrian 感谢您的回答。但是,我认为身体并不重要。问题实际上是如何根据每个调用者拥有的值进行同步
  • body 很重要,因为makeUpdate 是需要同步的,或者更具体地说,访问makeUpdate 正在操作的数据是需要同步的。
  • @Adrian 不,不是访问需要同步的数据,而是 makeUpdate() 中的代码。想象一下它只是在某个地方调用了一个服务,我们应该把它当作一个黑盒
  • 也许你可以进一步解释你的情况,因为一般来说,访问数据是唯一需要同步的事情。

标签: go concurrency parallel-processing


【解决方案1】:

正如 cmets 建议的那样 - 您需要保护数据访问而不是功能访问。

实现这一点的最简单方法是创建一个带锁的结构类型 - 并将关键功能更新附加为方法,例如

type MyData struct {
        l sync.Mutex
        // add any other task related attributes here too
}

// makeUpdate *MUST* use a pointer to our struct (i.e. 'm *MyData')
// as Mutex logic breaks if copied (so no 'm MyData')
func (m *MyData) makeUpdate(id int) {
        m.l.Lock()
        defer m.l.Unlock()

        fmt.Printf("better makeUpdate(%d)\n", id) 

        // do critical stuff here

        // don't dilly-dally - lock is still being used - so return quickly
}

playground 中试试这个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多