This commit is contained in:
Xargin
2016-10-05 13:56:07 +08:00
parent 4991d9c975
commit 28fe19ecc7
6 changed files with 10 additions and 11 deletions

View File

@@ -73,7 +73,7 @@ go func() { x = make([]int, 1000000) }()
x[999999] = 1 // NOTE: undefined behavior; memory corruption possible!
```
最后一个语句中的x的值是未定义的其可能是nil或者也可能是一个长度为10的slice也可能是一个度为1,000,000的slice。但是回忆一下slice的三个组成部分指针(pointer)、长度(length)和容量(capacity)。如果指针是从第一个make调用来而长度从第二个make来x就变成了一个混合体一个自称长度为1,000,000但实际上内部只有10个元素的slice。这样导致的结果是存储999,999元素的位置会碰撞一个遥远的内存位置这种情况下难以对值进行预测而且定位和debug也会变成噩梦。这种语义雷区被称为未定义行为对C程序员来说应该很熟悉幸运的是在Go语言里造成的麻烦要比C里小得多。
最后一个语句中的x的值是未定义的其可能是nil或者也可能是一个长度为10的slice也可能是一个度为1,000,000的slice。但是回忆一下slice的三个组成部分指针(pointer)、长度(length)和容量(capacity)。如果指针是从第一个make调用来而长度从第二个make来x就变成了一个混合体一个自称长度为1,000,000但实际上内部只有10个元素的slice。这样导致的结果是存储999,999元素的位置会碰撞一个遥远的内存位置这种情况下难以对值进行预测而且debug也会变成噩梦。这种语义雷区被称为未定义行为对C程序员来说应该很熟悉幸运的是在Go语言里造成的麻烦要比C里小得多。
尽管并发程序的概念让我们知道并发并不是简单的语句交叉执行。我们将会在9.4节中看到数据竞争可能会有奇怪的结果。许多程序员甚至一些非常聪明的人也还是会偶尔提出一些理由来允许数据竞争比如“互斥条件代价太高”“这个逻辑只是用来做logging”“我不介意丢失一些消息”等等。因为在他们的编译器或者平台上很少遇到问题可能给了他们错误的信心。一个好的经验法则是根本就没有什么所谓的良性数据竞争。所以我们一定要避免数据竞争那么在我们的程序中要如何做到呢