A Beginning Look at Concurrency in Go

The Go language includes several unique features, many of which are found in other languages. The most interesting one however, is its support for concurrent programming. Instead of a traditional approach using locks and mutexes, concurrency in Go is based on communicating sequential processes. In Go, the paradigm is do not communicate by sharing memory; instead, share memory by communicating. Let’s take a brief look at two of Go’s fundamental concurrency constructs: goroutines and channels.

Goroutines

A goroutine is an independently executing function. The go statment is used to launch a goroutine.

In the above example, we execute the function greet in a separate goroutine. This goroutine executes independently of the program’s main goroutine. The main goroutine executes the entry point of every Go program, the main function in the main package.

Unfortunately, running this program results in no output. This is because the go statement returns immediately; the caller doesn’t wait. By the time the greet function was ready to output a greeting, the main goroutine had already finished and the program exited.

In order to receive the greeting, the two goroutines need to communicate. Goroutines communicate through channels.

Channels

A channel is a bidirectional or unidirectional connection between two goroutines, allowing them to communicate.

By using channels, we can receive a greeting from the greet function that's executing in a separate goroutine. In this version, greet sends the greeting to the shared channel; and main reads from it. The main goroutine, i.e., the goroutine executing main, will block until it receives a message from the shared channel.

Only the Beginning

There's a lot more to concurrency in Go. In future posts, we'll look at Go's other concurrency constructs and common concurrency patterns.