gpt4 book ai didi

Golang slice 附加和重新分配

转载 作者:IT王子 更新时间:2023-10-29 02:32:10 25 4
gpt4 key购买 nike

我最近一直在学习围棋,对重新分配发生时 slice 的行为有疑问。假设我有一片指向结构的指针,例如:

var a []*A

如果我要将这个 slice 传递给另一个函数,我的理解是在内部它按值传递一个 slice header ,它在一个单独的 goroutine 上运行并且只从 slice 中读取,而启动 goroutine 的函数继续附加到 slice ,这是一个问题吗?例如:

package main

type A struct {
foo int
}

func main() {
a := make([]*A, 0, 100)
ch := make(chan int)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
go read_slice(a, ch)
for i := 0; i < 100; i++ {
a = append(a, &A{i+100})
}
<-ch
}

func read_slice(a []*A, ch chan int) {
for i := range a {
fmt.Printf("%d ", a[i].foo)
}
ch <- 1
}

所以根据我的理解,由于 read_slice() 函数在它自己的 goroutine 上运行,带有 slice 头的副本,它有一个指向当前后备数组的底层指针和调用它时的大小我通过它可以访问 foo 的。

但是,当另一个 goroutine 附加到 slice 时,它会在超过容量时触发重新分配。 go 运行时是否不会将内存释放给 read_slice() 中使用的旧支持数组,因为在该函数中有对它的引用?

我尝试使用“go run -race slice.go”运行它,但没有报告任何内容,但我觉得我可能在这里做错了什么?任何指针将不胜感激。

谢谢!

最佳答案

在没有对支持数组的引用之前,GC 不会收集支持数组。该计划中没有比赛。

考虑没有 goroutines 的场景:

  a := make([]*A, 0, 100)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
b := a
for i := 0; i < 100; i++ {
b = append(b, &A{i+100})
}

当 append to b 分配一个新的支持数组时, slice a 将继续使用前 100 个指针引用支持数组。 slice a 没有留下对后备数组的悬空引用。

现在将 goroutine 添加到场景中:

  a := make([]*A, 0, 100)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
b := a
go read_slice(a, ch)
for i := 0; i < 100; i++ {
b = append(b, &A{i+100})
}

goroutine 可以愉快地使用 slice a。没有悬挂的引用。

现在考虑问题中的程序。它在功能上与此处的最后一个片段相同。

关于Golang slice 附加和重新分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47086773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com