Concurrency Golang并发阵列访问

Concurrency Golang并发阵列访问,concurrency,synchronization,go,thread-safety,locking,Concurrency,Synchronization,Go,Thread Safety,Locking,当每个goroutine都在一个片上工作,指向相同的底层数组但没有重叠时,从多个goroutine访问同一数组安全吗 比如: 想象一下“WorkOn”会做一些奇特的事情。只要你能保证这些区域不会重叠,就可以了 我所说的保证是指:任何在sliceA上工作的人都不应该被允许做sliceA=append(sliceA,a,b,c)。因为那时它将开始运行到sliceB的领域 以下是一些与此相关的文档: 这涉及到一个新的语言元素:3-index-slices: Go 1.2增加了在现有阵列或切片上使用切片

当每个goroutine都在一个片上工作,指向相同的底层数组但没有重叠时,从多个goroutine访问同一数组安全吗

比如:


想象一下“WorkOn”会做一些奇特的事情。

只要你能保证这些区域不会重叠,就可以了

我所说的保证是指:任何在
sliceA上工作的人都不应该被允许做
sliceA=append(sliceA,a,b,c)
。因为那时它将开始运行到
sliceB
的领域

以下是一些与此相关的文档: 这涉及到一个新的语言元素:3-index-slices

Go 1.2增加了在现有阵列或切片上使用切片操作时指定容量和长度的功能。切片操作通过描述已创建数组或切片的连续部分来创建新切片:

片的容量是片可以容纳的最大元素数,即使在重新选择后也是如此;它反映了基础数组的大小。在本例中,slice变量的容量为8

Go 1.2添加了新语法,允许切片操作指定容量和长度。第二个冒号引入容量值,该值必须小于或等于源片或阵列的容量,并根据原点进行调整。比如说,

将切片设置为具有与前面示例中相同的长度,但其容量现在只有5个元素(7-2)。无法使用此新切片值访问原始数组的最后三个元素

在这种三索引表示法中,缺少的第一个索引([:i:j])默认为零,但必须始终显式指定其他两个索引。Go的未来版本可能会引入这些指数的默认值

详情请参阅


事实上,吉姆的答案可能是错误的。这取决于……:)

例如,如果您使用的是[]uint8,则

p[2] = 5
本质上是这样吗

tmp = p[0..3] // this is 32 bit
tmp[2] = 5
p[0..3] = tmp // yeah this is all fake syntax but you'll get it
这是因为您的CPU是32位(甚至64位)。所以这实际上更有效,尽管它看起来更复杂

但正如您所看到的,您正在编写p[0,1,3],尽管您只打算编写p[2]。这会产生一些有趣的bug来调试!:)


如果您的数据是指向数据的指针,则不应出现此问题,因为数组保证存储在内存中,这样只要您的数据与本机指令集一样长,就不会出现此问题。

我无法想象这会是一个问题。是的。太短,无法回答。Thx,我担心的是,这必须由互斥来保护,因为它是单个数组。很高兴听到这是安全的。从Java的内存模型中,我知道缓存刷新/刷新与线程间可见性效果之间的区别。既然Go允许通过goroutines共享记忆,这个问题就直接出现在我的脑海里。虽然我不太确定是谁干的。Go运行时是否能够刷新单个数组的某些部分?随着时间的推移,我真的应该深入研究一下它的实现。对Go并发模型的一个担忧是,它没有提供防止并行使用共享数据的保护。没关系,你是程序员,承担风险。确保不会因为共享内存而出现意外的争用情况是您的工作。Occam是一种采取相反立场的语言,它在语言语法中提供抗锯齿规则,并在编译器中提供并行使用检查。这是非常复杂的;也许有一天围棋会有类似的东西。@Rick-777可能和Occam不在同一个联盟中,但围棋确实有一个很棒的种族检测器,可以帮助防止不安全并发访问的陷阱。Yes Go有一个有用的运行时竞赛分析器,它将有助于解决上面提出的问题。(Occam的种族分析器是一个静态编译时的东西。)为什么要投否决票?没有解释性的评论是不好的。。。尤其是我的32位手臂上有个bug…答案有点难理解-我想我理解你的意思只是因为我对记忆障碍有模糊的经验。但我认为关键是,不要对操作的原子性做出假设。我认为问题在于,你从来没有明确解释过32位计算机一次访问32位内存,因此如果你的切片元素类型小于该类型,那么你可能实际上正在访问和存储切片的一个禁止访问的部分。
slice = array[2:4:7]
p[2] = 5
tmp = p[0..3] // this is 32 bit
tmp[2] = 5
p[0..3] = tmp // yeah this is all fake syntax but you'll get it