Goroutines cannot directly return values; instead, they typically send results back through channels.
Key takeaways:
Concurrency allows multiple tasks to be performed simultaneously, enhancing efficiency and performance in applications.
Go utilizes goroutines and channels to implement concurrency.
Goroutines allow functions to run concurrently, initiated with the
go
keyword.Channels enable safe communication and synchronization between goroutines.
Mastering concurrency in Go boosts performance and helps tackle complex software challenges effectively.
Nowadays, the ability to efficiently manage multiple tasks simultaneously is more important than ever. Imagine building applications that can handle thousands of requests at once, just like how major platforms such as Netflix manage their streaming services.
This is where concurrency comes into play.
Concurrency means to perform multiple tasks at the same time. In simpler words, when working and progressing with more tasks simultaneously is known as concurrency.
In the Go language, we can use concurrency using goroutines and channels. Let's now explore both the goroutines and channels in detail.
Functions that can run concurrently with other functions are known as goroutines. A goroutine can be created using the go
keyword.
go myfunc()
Let's now look at the working of a goroutine using a coding example.
package mainimport ("fmt""time")func myfunc(str string) {for i := 0; i < 3; i++ {time.Sleep(10 * time.Millisecond)fmt.Println(str)}}func main() {go myfunc("learn")myfunc("create")}
Lines 8–13: This function, named myfunc
, takes a string argument str
and prints it three times with a short delay between each print. It uses a for
loop and the time.Sleep
function to introduce a delay of 10 milliseconds between each print.
Line 16: This line starts a new goroutine by using the go
keyword before calling the myfunc
function with the argument "learn".
Line 17: This line calls the myfunc
function with the argument "create" in the main goroutine. The key point here is that the go myfunc("learn")
line launches a goroutine, and myfunc("create")
continues executing in the main goroutine without waiting for the goroutine to complete. As a result, "create" and "learn" will be printed concurrently, and the order of the output may vary each time you run the program due to the concurrent execution of goroutines.
Let's now learn about channels in Go.
Channels in Go serve as typed conduits for sending and receiving values using the channel operator, <-
.
You can use the channel operator in the following ways:
chl <- x
: Sends the value x
to the channel chl
.
x := <-chl
: Receives a value from the channel chl
and assigns it to the variable x
.
The direction of the arrow indicates the flow of data.
Similar to maps and slices, channels must be created before being utilized:
chl := make(chan int)
By default, sending and receiving operations on channels block until the other side is ready. This inherent behavior enables goroutines to synchronize without requiring explicit locks or condition variables.
The following program sums the numbers in a slice by distributing the computational work between two goroutines. The final result is calculated once both goroutines have completed their respective computations.
package mainimport "fmt"func score(n []int, ch chan int) {score := 0for _, i := range n {score += i}ch <- score // send score to c}func main() {slice := []int{3, 2, 6, -9, 4, 0}ch := make(chan int)go score(slice[:len(slice)/2], ch)go score(slice[len(slice)/2:], ch)a, b := <-ch, <-ch // receive from cfmt.Println(a, b, a+b)}
Lines 5–11: This function, score
, takes a slice of integers n
and a channel of integers ch
as parameters. It iterates through the elements of the slice, calculating the sum of all the numbers. The calculated score is sent to the channel ch
using ch <- score
.
Lines 13–22: The main
function starts by creating a slice of integers named slice
. It then creates a channel of integers, ch
, using make(chan int)
. Two goroutines are launched concurrently using the go
keyword. Each goroutine calculates the sum of a different half of the slice
and sends the result to the channel ch
. The main goroutine receives the two results from the channel ch
using the expressions a, b := <-ch, <-ch
. Finally, it prints the received values and their score using fmt.Println(a, b, a+b)
.
In summary, this code demonstrates using goroutines and channels in Go to concurrently calculate the sums of two halves of a slice of integers. The main goroutine then receives these results from the channel, prints them, and displays their sum. Using channels ensures synchronization and proper communication between the concurrently running goroutines.
Incorporating concurrency in the programming toolkit, especially with Go's goroutines and channels, can significantly improve the performance and responsiveness of the applications. By allowing multiple tasks to run simultaneously and enabling seamless communication between them, we can tackle complex problems more efficiently.
Haven’t found what you were looking for? Contact Us
Free Resources