Goroutines cannot directly return values; instead, they typically send results back through channels.
What is Go concurrency?
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
gokeyword.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.
What is concurrency?
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.
Goroutines
Functions that can run concurrently with other functions are known as goroutines. A goroutine can be created using the go keyword.
go myfunc()
Goroutines code example
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")}
Explanation
Lines 8–13: This function, named
myfunc, takes a string argumentstrand prints it three times with a short delay between each print. It uses aforloop and thetime.Sleepfunction to introduce a delay of 10 milliseconds between each print.Line 16: This line starts a new goroutine by using the
gokeyword before calling themyfuncfunction with the argument "learn".Line 17: This line calls the
myfuncfunction with the argument "create" in the main goroutine. The key point here is that thego myfunc("learn")line launches a goroutine, andmyfunc("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
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 valuexto the channelchl.x := <-chl: Receives a value from the channelchland assigns it to the variablex.
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.
Goroutines with channel code example
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)}
Explanation
Lines 5–11: This function,
score, takes a slice of integersnand a channel of integerschas parameters. It iterates through the elements of the slice, calculating the sum of all the numbers. The calculated score is sent to the channelchusingch <- score.Lines 13–22: The
mainfunction starts by creating a slice of integers namedslice. It then creates a channel of integers,ch, usingmake(chan int). Two goroutines are launched concurrently using thegokeyword. Each goroutine calculates the sum of a different half of thesliceand sends the result to the channelch. The main goroutine receives the two results from the channelchusing the expressionsa, b := <-ch, <-ch. Finally, it prints the received values and their score usingfmt.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.
Conclusion
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.
Frequently asked questions
Haven’t found what you were looking for? Contact Us
Can a goroutine return a value?
What is a select statement in Go?
Free Resources