Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 使用片类型输入和输出通道执行并发工作程序例程_Go_Concurrency_Slice_Channel_Worker - Fatal编程技术网

Go 使用片类型输入和输出通道执行并发工作程序例程

Go 使用片类型输入和输出通道执行并发工作程序例程,go,concurrency,slice,channel,worker,Go,Concurrency,Slice,Channel,Worker,我对围棋语言比较陌生。即使我不希望如此,我可能会用一个愚蠢的问题来打扰你。我先道歉,以防万一 下面是我的示例:我定义了一个worker函数,它作为一组并发Go例程从main调用。输入和输出数据通过片类型[]int的输入和输出通道提供。在一种情况下,一切正常,在另一种情况下,结果有误。请参阅代码中的注释和代码下面的程序输出 老实说,我看不出这两种代码变体之间的实际区别。我错过了什么?谢谢你的建议 package main import "fmt" import "runtime" func w

我对围棋语言比较陌生。即使我不希望如此,我可能会用一个愚蠢的问题来打扰你。我先道歉,以防万一

下面是我的示例:我定义了一个worker函数,它作为一组并发Go例程从main调用。输入和输出数据通过片类型[]int的输入和输出通道提供。在一种情况下,一切正常,在另一种情况下,结果有误。请参阅代码中的注释和代码下面的程序输出

老实说,我看不出这两种代码变体之间的实际区别。我错过了什么?谢谢你的建议

package main

import "fmt"
import "runtime"

func worker(x_ch <-chan []int, y_ch chan<- []int, wid int) {

    for x := range x_ch {
        y := x
        fmt.Println("   worker", wid, "x:", x)
        fmt.Println("   worker", wid, "y:", y)
        y_ch <- y
    }
}

func main() {

    n_workers := runtime.NumCPU()
    n_len := 4
    n_jobs := 4
    x := make([]int, n_len)
    x_ch := make(chan []int, 10)
    y_ch := make(chan []int, 10)

    for j := 0; j < n_workers; j++ { go worker(x_ch, y_ch, j) }

    for k := 0; k < n_jobs; k++ {

//      variant 1: works!
        x = []int{k, k, k, k}

//      variant 2: doesn't work!
//      for i := range x { x[i] = k }

        fmt.Println("main x:", k, x)
        x_ch <- x
    }

    close(x_ch)

    for i := 0; i < n_jobs; i++ {
        z := <- y_ch
        fmt.Println("       main y:", i, z)
    }
}
输出变量2错误:

main x: 0 [0 0 0 0]
main x: 1 [1 1 1 1]
main x: 2 [2 2 2 2]
main x: 3 [3 3 3 3]
   worker 3 x: [3 3 3 3]
   worker 3 y: [3 3 3 3]
       main y: 0 [3 3 3 3]
   worker 0 x: [2 2 2 2]
   worker 0 y: [3 3 3 3]
       main y: 1 [3 3 3 3]
   worker 1 x: [1 1 1 1]
   worker 1 y: [3 3 3 3]
       main y: 2 [3 3 3 3]
   worker 2 x: [3 3 3 3]
   worker 2 y: [3 3 3 3]
       main y: 3 [3 3 3 3]

不同之处在于,在变体1中,每次都发送不同的切片,而在变体2中,每次在for循环上方创建的切片都发送相同的切片。在不创建新切片的情况下,您只需将同一切片的元素设置为不同的值,这样goroutine在查看切片时就会看到切片中出现的任何值。在变量2中,main将始终看到[3],因为这是经过4次循环后的最终值。切片对象的值包含对底层元素的引用,而不是元素本身的引用。切片有很好的解释。

非常感谢您的解释,现在我知道问题出在哪里了。我添加了一些调试代码来输出指针地址,结果是稍微重新格式化了输出:

备选案文1:

main 0 x=[0 0 0 0] &x=0x1830e180 &x[0]=0x1830e1e0
main 1 x=[1 1 1 1] &x=0x1830e180 &x[0]=0x1830e230
main 2 x=[2 2 2 2] &x=0x1830e180 &x[0]=0x1830e270
main 3 x=[3 3 3 3] &x=0x1830e180 &x[0]=0x1830e2a0
    worker 3 x=[3 3 3 3] &x=0x1830e1d0 &x[0]=0x1830e2a0
    worker 3 y=[3 3 3 3] &y=0x1830e2e0 &y[0]=0x1830e2a0
        main 0 y=[3 3 3 3] &y=0x1830e2d0 &y[0]=0x1830e2a0
    worker 0 x=[0 0 0 0] &x=0x1830e1a0 &x[0]=0x1830e1e0
    worker 0 y=[0 0 0 0] &y=0x1830e370 &y[0]=0x1830e1e0
        main 1 y=[0 0 0 0] &y=0x1830e360 &y[0]=0x1830e1e0
    worker 1 x=[1 1 1 1] &x=0x1830e1b0 &x[0]=0x1830e230
    worker 1 y=[1 1 1 1] &y=0x1830e400 &y[0]=0x1830e230
        main 2 y=[1 1 1 1] &y=0x1830e3f0 &y[0]=0x1830e230
    worker 2 x=[2 2 2 2] &x=0x1830e1c0 &x[0]=0x1830e270
    worker 2 y=[2 2 2 2] &y=0x1830e480 &y[0]=0x1830e270
        main 3 y=[2 2 2 2] &y=0x1830e470 &y[0]=0x1830e270
备选案文2:

main 0 x=[0 0 0 0] &x=0x1830e180 &x[0]=0x1830e190
main 1 x=[1 1 1 1] &x=0x1830e180 &x[0]=0x1830e190
main 2 x=[2 2 2 2] &x=0x1830e180 &x[0]=0x1830e190
main 3 x=[3 3 3 3] &x=0x1830e180 &x[0]=0x1830e190
    worker 3 x=[3 3 3 3] &x=0x1830e1d0 &x[0]=0x1830e190
    worker 3 y=[3 3 3 3] &y=0x1830e2a0 &y[0]=0x1830e190
        main 0 y=[3 3 3 3] &y=0x1830e290 &y[0]=0x1830e190
    worker 0 x=[3 3 3 3] &x=0x1830e1a0 &x[0]=0x1830e190
    worker 0 y=[3 3 3 3] &y=0x1830e330 &y[0]=0x1830e190
        main 1 y=[3 3 3 3] &y=0x1830e320 &y[0]=0x1830e190
    worker 1 x=[3 3 3 3] &x=0x1830e1b0 &x[0]=0x1830e190
    worker 1 y=[3 3 3 3] &y=0x1830e3c0 &y[0]=0x1830e190
        main 2 y=[3 3 3 3] &y=0x1830e3b0 &y[0]=0x1830e190
    worker 2 x=[3 3 3 3] &x=0x1830e1c0 &x[0]=0x1830e190
    worker 2 y=[3 3 3 3] &y=0x1830e440 &y[0]=0x1830e190
        main 3 y=[3 3 3 3] &y=0x1830e430 &y[0]=0x1830e190
main 0 x=[0 0 0 0] &x=0x1830e180 &x[0]=0x1830e190
main 1 x=[1 1 1 1] &x=0x1830e180 &x[0]=0x1830e190
main 2 x=[2 2 2 2] &x=0x1830e180 &x[0]=0x1830e190
main 3 x=[3 3 3 3] &x=0x1830e180 &x[0]=0x1830e190
    worker 3 x=[3 3 3 3] &x=0x1830e1d0 &x[0]=0x1830e190
    worker 3 y=[3 3 3 3] &y=0x1830e2a0 &y[0]=0x1830e190
        main 0 y=[3 3 3 3] &y=0x1830e290 &y[0]=0x1830e190
    worker 0 x=[3 3 3 3] &x=0x1830e1a0 &x[0]=0x1830e190
    worker 0 y=[3 3 3 3] &y=0x1830e330 &y[0]=0x1830e190
        main 1 y=[3 3 3 3] &y=0x1830e320 &y[0]=0x1830e190
    worker 1 x=[3 3 3 3] &x=0x1830e1b0 &x[0]=0x1830e190
    worker 1 y=[3 3 3 3] &y=0x1830e3c0 &y[0]=0x1830e190
        main 2 y=[3 3 3 3] &y=0x1830e3b0 &y[0]=0x1830e190
    worker 2 x=[3 3 3 3] &x=0x1830e1c0 &x[0]=0x1830e190
    worker 2 y=[3 3 3 3] &y=0x1830e440 &y[0]=0x1830e190
        main 3 y=[3 3 3 3] &y=0x1830e430 &y[0]=0x1830e190