具有单个读取器和单个写入器的Golang作业安全

时间:2019-07-01 09:46:17

标签: go concurrency atomic

说我有两个例程:

var sequence int64

// writer
for i := sequence; i < max; i++ {
  doSomethingWithSequence(i)
  sequence = i
}

// reader
for {
  doSomeOtherThingWithSequence(sequence)
}

那么如果没有atomic,我能渡过难关吗?

我能想到的一些潜在风险:

  1. 重新排序(对于作者来说,更新sequence发生在doSomething之前),但我可以接受。

  2. sequence在内存中未正确对齐,因此读者可能会看到部分更新的i。在具有x86_64的(最新内核)Linux上运行, 我们可以排除吗?

  3. go编译器“巧妙地”优化了读取器,因此对i的访问永远不会进入内存,而是cached会进入寄存器。可以吗?

  4. 还有什么?

1 个答案:

答案 0 :(得分:0)

Go的座右铭:Do not communicate by sharing memory; instead, share memory by communicating。大多数情况下,这是一种有效的最佳实践。

  1. 如果您关心订购,那么您就关心同步两个goroutine。
  2. 我认为这是不可能的。无论如何,如果正确设计同步,这些都不是您应该担心的事情。
  3. 与上面相同。

幸运的是,Go集成了data race detector。尝试使用go run -race运行示例。您可能会看到sequence变量上发生竞争情况。