通道元素类型太大的 Golang



我正在编写一个并行处理矩阵的程序。

我的矩阵是使用常量n创建的。

const n = 10

通道使用以下代码创建:

a := make(chan [n][n]int)
这对于低于12

值的任何值n但是任何更大的值都可以正常工作,并给出以下错误:

channel element type too large (>64kB)

查看教程等,似乎缓冲通道可能是解决此问题的方法,但我尝试使用以下代码执行此操作,并给出了相同的错误:

a := make(chan [n][n]int, 1000)

我是否正确使用了缓冲通道,或者它们不是解决此问题的方法?关于我如何推进这项工作的任何提示,非常感谢。

编辑:根据给出的答案和评论,我现在正在尝试创建一个全局矩阵,该矩阵是空白的,并且例程可以写入。

const n int = 1024
blank [n][n]int

我不确定如何在全球范围内声明它,并尝试了上述方法来解决此问题。是否需要全局初始化?我似乎尝试的一切都会出错。

是否缓冲的通道与此无关,错误不在于存储元素的空间,而在于单个元素的大小。通道元素类型的大小限制是实现细节/限制,您无法对此执行任何操作。

如果你试图使用违反这一点的元素类型,这表明你做错了什么(你不应该做的事情)。每当您在通道上发送值时,都会复制该值。因此,在通道上发送>64KB 值并不是真正有效。

而是选择较小的元素类型。需要最少更改的选择是使用指向您的类型的指针:*[n][n]int

a := make(chan *[n][n]int)

然后,当然你必须在频道上发送指针,你会从它收到指针,例如:

const n = 132
a := make(chan *[n][n]int)
go func() {
var v [n][n]int
a <- &v // Sending a pointer
}()
v2 := <-a
fmt.Println(v2)  // It's a pointer
fmt.Println(*v2) // It's an array value

在Go Playground上尝试一下。

您还应该记住,由于现在我们在通道上发送/接收指针,它将指向相同的数组值,因此修改指向的值将修改我们在通道上发送其地址的同一数组。如果不需要,请在发送前制作副本,并发送副本的地址:

var v [n][n]int
// Making a copy:
v2 := v
a <- &v2 // Sending address of the copy

您还应该考虑使用切片而不是数组。

编辑:

声明全局数组非常简单:

var result [n][n]int

(它必须在文件范围内的其他块之外。

最新更新