Concurrency and Packages
Channel Pipeline
Channels can connect pipeline stages while each stage keeps a small, deterministic responsibility.
channel pipeline
Start a producer goroutine, transform each value in the main goroutine, and join through channel close semantics.
Channel Pipeline
channel_pipeline.go
Replay: real traced execution (multi-file project)
package main
import "fmt"
func main() {
var count = 3
inputs := make(chan int)
outputs := []int{}
go func() {
for value := 1; value <= count; value++ {
inputs <- value
}
close(inputs)
}()
for value := range inputs {
outputs = append(outputs, value*value)
}
total := 0
for _, value := range outputs {
total += value
}
fmt.Println("count=", count)
fmt.Println("outputs=", outputs)
fmt.Println("total=", total)
}
package main
import "fmt"
func main() {
var count = 2
inputs := make(chan int)
outputs := []int{}
go func() {
for value := 1; value <= count; value++ {
inputs <- value
}
close(inputs)
}()
for value := range inputs {
outputs = append(outputs, value*value)
}
total := 0
for _, value := range outputs {
total += value
}
fmt.Println("count=", count)
fmt.Println("outputs=", outputs)
fmt.Println("total=", total)
}
package main
import "fmt"
func main() {
var count = 4
inputs := make(chan int)
outputs := []int{}
go func() {
for value := 1; value <= count; value++ {
inputs <- value
}
close(inputs)
}()
for value := range inputs {
outputs = append(outputs, value*value)
}
total := 0
for _, value := range outputs {
total += value
}
fmt.Println("count=", count)
fmt.Println("outputs=", outputs)
fmt.Println("total=", total)
}
count ← 3, inputs ← (chan int)(⟨addr A⟩), outputs ← []int{}
5func main() {6 var count→ 3 = 3 //@count=2, 47 inputs→ (chan int)(⟨addr A⟩) := make(chan int)8 outputs→ []int{} := []int{}910 go func() {11 for value := 1; value <= count; value++ {12 inputs <- value13 }14 close(inputs)15 }()for value := 1; value <= count; value++
pass 1 of 310go func() {11 for value1 := 1; value <= count3; value++ {12 inputs(chan int)(⟨addr A⟩) <- value113 }All 3 passes — pass 1 is the card above pass value1 1 2 2 3 3 outputs ← []int{1}
pass 1 of 317for value1 := range inputs(chan int)(⟨addr A⟩) {18 outputs→ []int{1} = append(outputs, value1*value)19}All 3 passes — pass 1 is the card above pass valueoutputs1 1 []int{} → []int{1} 2 2 []int{1} → []int{1, 4} 3 3 []int{1, 4} → []int{1, 4, 9} close(inputs)
13 }14 close(inputs(chan int)(⟨addr A⟩))15}()total ← 0
21total→ 0 := 022for _, value := range outputs {total ← 1
pass 1 of 321total := 022for _, value1 := range outputs[]int{1, 4, 9} {23 total→ 1 += value124}All 3 passes — pass 1 is the card above pass valuetotal1 1 0 → 1 2 4 1 → 5 3 9 5 → 14 fmt.Println("count=", count)
26 fmt.Println("count=", count3)27 fmt.Println("outputs=", outputs[]int{1, 4, 9})28 fmt.Println("total=", total14)29}outputcount= 3 outputs= [1 4 9] total= 14
count ← 2, inputs ← (chan int)(⟨addr A⟩), outputs ← []int{}
5func main() {6 var count→ 2 = 27 inputs→ (chan int)(⟨addr A⟩) := make(chan int)8 outputs→ []int{} := []int{}910 go func() {11 for value := 1; value <= count; value++ {12 inputs <- value13 }14 close(inputs)15 }()for value := 1; value <= count; value++
pass 1 of 210go func() {11 for value1 := 1; value <= count2; value++ {12 inputs(chan int)(⟨addr A⟩) <- value113 }for value := 1; value <= count; value++
pass 2 of 210go func() {11 for value2 := 1; value <= count2; value++ {12 inputs(chan int)(⟨addr A⟩) <- value213 }outputs ← []int{1}
pass 1 of 217for value1 := range inputs(chan int)(⟨addr A⟩) {18 outputs→ []int{1} = append(outputs, value1*value)19}outputs ← []int{1, 4}
pass 2 of 211 for value := 1; value <= count; value++ {12 inputs(chan int)(⟨addr A⟩) <- value213 }14 close(inputs(chan int)(⟨addr A⟩))15}()1617for value2 := range inputs(chan int)(⟨addr A⟩) {18 outputs→ []int{1, 4} = append(outputs, value2*value)19}total ← 0
21total→ 0 := 022for _, value := range outputs {total ← 1
pass 1 of 221total := 022for _, value1 := range outputs[]int{1, 4} {23 total→ 1 += value124}total ← 5
pass 2 of 221total := 022for _, value4 := range outputs[]int{1, 4} {23 total→ 5 += value424}fmt.Println("count=", count)
26 fmt.Println("count=", count2)27 fmt.Println("outputs=", outputs[]int{1, 4})28 fmt.Println("total=", total5)29}outputcount= 2 outputs= [1 4] total= 5
count ← 4, inputs ← (chan int)(⟨addr A⟩), outputs ← []int{}
5func main() {6 var count→ 4 = 47 inputs→ (chan int)(⟨addr A⟩) := make(chan int)8 outputs→ []int{} := []int{}910 go func() {11 for value := 1; value <= count; value++ {12 inputs <- value13 }14 close(inputs)15 }()for value := 1; value <= count; value++
pass 1 of 410go func() {11 for value1 := 1; value <= count4; value++ {12 inputs(chan int)(⟨addr A⟩) <- value113 }All 4 passes — pass 1 is the card above pass value1 1 2 2 3 3 4 4 outputs ← []int{1}
pass 1 of 417for value1 := range inputs(chan int)(⟨addr A⟩) {18 outputs→ []int{1} = append(outputs, value1*value)19}All 4 passes — pass 1 is the card above pass valueoutputs1 1 []int{} → []int{1} 2 2 []int{1} → []int{1, 4} 3 3 []int{1, 4} → []int{1, 4, 9} 4 4 []int{1, 4, 9} → []int{1, 4, 9, 16} total ← 0
21total→ 0 := 022for _, value := range outputs {total ← 1
pass 1 of 421total := 022for _, value1 := range outputs[]int{1, 4, 9, 16} {23 total→ 1 += value124}All 4 passes — pass 1 is the card above pass valuetotal1 1 0 → 1 2 4 1 → 5 3 9 5 → 14 4 16 14 → 30 fmt.Println("count=", count)
26 fmt.Println("count=", count4)27 fmt.Println("outputs=", outputs[]int{1, 4, 9, 16})28 fmt.Println("total=", total30)29}outputcount= 4 outputs= [1 4 9 16] total= 30