为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 并发数组访问

Golang 并发数组访问

Go
萧十郎 2021-07-26 17:26:28
当每个 goroutine 在一个切片上工作,指向相同的底层数组但没有重叠时,从多个 goroutine 访问同一个数组是否安全?像:var arr [100]intsliceA := arr[:50]sliceB := arr[50:]go WorkOn(sliceA)go WorkOn(sliceB)想象一下“WorkOn”会做一些奇特的事情。
查看完整描述

2 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

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

担保我的意思是:任何人的作品上sliceA,应该不会被允许做sliceA = append(sliceA, a, b, c)。因为那样它就会开始跑进sliceB的领地。

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

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

var array [10]int
slice := array[2:4]

切片的容量是切片可以容纳的最大元素数,即使在重新切片之后;它反映了底层数组的大小。在本例中,切片变量的容量为 8。

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

slice = array[2:4:7]

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

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

更多细节在设计文件中


查看完整回答
反对 回复 2021-08-02
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

实际上 jimt 的回答可能是错误的。这取决于... :)


例如,如果您使用的是 []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]。这可以创建一些有趣的错误来调试!:)


如果您的数据是例如指向您的数据的指针,那么这个问题不应该发生,因为数组保证存储在内存中,这样只要您的数据与您的本机指令集一样长,这个问题就不会发生。


查看完整回答
反对 回复 2021-08-02
  • 2 回答
  • 0 关注
  • 582 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信