## DEV Community

Srinivas Kandukuri

Posted on

# Understanding Concurrency in Go: A Simple Pipeline Example

Go is known for its powerful concurrency features, and one of the elegant ways to leverage concurrency is through goroutines and channels. In this article, we'll explore a simple yet illustrative example of a concurrent pipeline using goroutines and channels in Go.

The Code Overview
Let's take a look at the Go code:

``````package main

import "fmt"

func main() {
// Step 1: Generate a channel of integers
c := gen(2, 3)

// Step 2: Square the numbers concurrently
out := sq(c)

// Step 3: Print the results
fmt.Println(<-out)
fmt.Println(<-out)
}

``````

The code defines a main function, where a pipeline of concurrent operations is orchestrated.

Generating Numbers Concurrently

``````func gen(nums ...int) <-chan int {
out := make(chan int)

go func() {
for _, n := range nums {
out <- n
}
close(out)
}()

return out
}

``````

The gen function generates a channel of integers. It accepts a variadic number of integers, creates a channel (out), and concurrently sends each number into the channel using a goroutine. The channel is closed once all numbers are sent.

Squaring Numbers Concurrently

``````func sq(in <-chan int) <-chan int {
out := make(chan int)

go func() {
for n := range in {
out <- n * n
}
close(out)
}()

return out
}

``````

The sq function squares numbers concurrently. It takes an input channel (in) and produces an output channel (out). The function reads from the input channel in a loop, squares each number, and sends the squared result to the output channel. Finally, the output channel is closed.

Orchestrating the Pipeline
The main function combines these operations:

gen(2, 3) generates a channel with the numbers 2 and 3.
sq(c) squares the numbers concurrently, creating an output channel.
<-out retrieves the squared result from the output channel and prints it.

Running the Code
When you run this code, you'll observe that the squaring operation is performed concurrently for each input number. This example demonstrates a simple yet powerful use of goroutines and channels to create a concurrent pipeline.

In summary, Go's goroutines and channels make it easy to design concurrent systems, and understanding these concepts is essential for writing efficient and scalable Go programs. The provided example serves as a starting point for exploring more complex concurrent patterns in Go.

Feel free to experiment with the code, modify the input numbers, and observe how Go's concurrency features elegantly handle the processing of data concurrently.

Happy coding in Go!