I am relatively new to the Go language. Even though I don't hope so, I maybe bother you with a silly question. My apologies upfront, just in case...
Here's my example: I defined a worker() function which is called from main() as a set of concurrent Go routines. Input and output data is provided via an input and an output channel both of slice type []int. In one case everything works as expected, in the other case the result is faulty. See the comments in the code and the program output below the code.
Honestly, I don't see the actual difference between both code variants. What did I miss here? Thank you for any advice!
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)
}
}
Correct output (variant 1):
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]
worker 2 x: [2 2 2 2]
worker 2 y: [2 2 2 2]
worker 1 x: [0 0 0 0]
worker 1 y: [0 0 0 0]
worker 0 x: [1 1 1 1]
worker 0 y: [1 1 1 1]
main y: 0 [3 3 3 3]
main y: 1 [2 2 2 2]
main y: 2 [0 0 0 0]
main y: 3 [1 1 1 1]
Wrong output (variant 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]