Go is a statically typed language that is famous for its concurrency support. It uses goroutines to run multiple threads in parallel, allowing the computer to perform multiple computations simultaneously. However, when multiple goroutines are running in parallel and accessing shared resources at the same time, ensuring stability in the read and write operations on that particular data becomes an issue. To address this issue, we have channels in Go that enable goroutines to communicate with each other, providing a sophisticated solution to race conditions in Go.
To create a channel in Go, use the following syntax:
ch := make(chan type)
Channels in Go are created using the make()
function, which takes the type of the value that will be sent over the channel as an argument.
Let’s take an example of two functions, printOne()
and printTwo()
, running in parallel in different goroutines. The printOne()
function prints 1
once after waiting for 10 seconds. The printTwo()
function prints 2
twice, with the second 2
being printed after 1
is printed. We’ll use channels to make the goroutines communicate with each other.
package mainimport ("fmt""time""sync")func printOne(ch chan bool, wg *sync.WaitGroup) {defer wg.Done()timeout := 20 * time.Second// Wait for the specified timeout duration or until a value is received on the channelselect {case <-time.After(timeout):fmt.Println("1")ch <- true // Send a true value on the channel}}func printTwo(ch chan bool, wg *sync.WaitGroup) {defer wg.Done()fmt.Println("2")check := <-ch // Receive a value from the channelif check {fmt.Println("2")}}func main() {fmt.Println("Process Started!")var wg sync.WaitGroupwg.Add(2)ch := make(chan bool)// Launch goroutines to execute printTwo and printOne functions concurrentlygo printTwo(ch, &wg)go printOne(ch, &wg)wg.Wait() // Wait for both goroutines to completefmt.Println("Process Ended!")}
Lines 9–17: The printOne()
function takes a channel and a WaitGroup
instance as input. It waits for 10 seconds and then prints 1
. After 1
has been printed, it puts a true
value in the channel.
Note: In Go, a wait group is a synchronization mechanism used to wait for a collection of goroutines to complete their execution before proceeding further. It allows us to coordinate and control the concurrent execution of goroutines.
Lines 19–26: The printTwo()
function takes a channel and a WaitGroup
instance as input. It prints 2
and then waits for the channel to give a TRUE value. When it gets TRUE from the channel, it prints the second 2
.
Lines 30–31: We initialize an instance of WaitGroup
and add 2
to the instance.
Line 32: We create a channel that will carry a value of type bool
.
Lines 33–34: We run the two functions in separate goroutines.
Line 35: We block the main()
function until all the goroutines are terminated.
Free Resources