go-102/ Golang concurrency

Make your app concurrent using goroutine and channel

https://github.com/gengo/goship

Goroutine

Goroutine works like the thread in java or any other multi-threading programming language, though the internal concept is different. Goroutine is more lightweight than processor thread. It takes little memory (on average 4~8 KB) than regular thread. Goroutines are managed by thread manager in runtime.

Let’s have a look to regular program without goroutine.

Simple program without goroutine

In the above program, the second function bar will execute after the completion of first function foo . See the example in go playground.

If we want to run these two function in two different thread / goroutine, we can simply put go keyword before these function.

Using goroutine (bad way)

The above program is executed concurrently (by default goruntime set single logical processor to process, so it’s running concurrently), see it in the playground. We called it bad program though it’s a concurrent program, because we use sleep to hold the application. The main routine will not wait for the two spawning goroutines. So we can’t see the output. We can use sync package’s WaitGroup to do it perfectly, let’s take a look at the example below:

Golang goroutine example

In the above example we used WaitGroup from sync package, you can learn more about it here. In line 11 we called the Add method passing 2 as integer, here 2 is the number of goroutine. Line 21 & 28 we called Done method which means the goroutine finished its task. Finally, in line 14 we called Wait method, this method will hold the main routine until the two routines finish. To learn more about the WaitGroup visit this link.


Channel

https://waimengmoan.gitbooks.io/go-applications/content/channel.jpg

By seeing the above picture you can imagine a little about channel. Channel is a pipe or a way to communicate between goroutines. Using channel you can pass data in three way

  • bi-directional: usually this type of channel can send and receive data (general signature: chan T)
  • send-only: this type of channel can only send data (signature: chan<- T)
  • receive-only: this type of channel can only receive data (signature: <-chan T)

Let’s take an example of simple channel declaration

Showing how to declare a channel, send message and receive message from channel

In the above example at line 6 we declare a channel (bi-directional unbuffered) type of string, that means it can only send or receives data type of strings. Between line 10–12 we declare an anonymous function in a goroutine, inside the function we send a string message to the channel (see line 11). We received the data at line 16.

We did not define any size of the channel, so by default it is zero size and this type of channel is called unbuffered channel. In unbffered channel the receiver will block until it gets any message and vice versa.

Let’s take a look to the example of a buffered channel

Simple buffered channel

In the above example we declared a buffered channel, to obtain this we simply passed the size as the second argument to make function. As you know the unbuffered channel block senders until a receiver is available or vice versa, it will be applicable for the buffered channel also if the size of the buffer is full. To close a channel we can use close() function.


Channel for synchronization

Let’s take a look at a real life example

Synchronization among goroutines using channel

The above example is trying to solve a real life http request responsibilities. We have two functionalities (one is to save the incoming data to database using saveToDatabase and other is to cache the data to redis using cacheToRedis) to complete to make the request done. We spawn two goroutines to do the task concurrently for us. After completing these two tasks then the main goroutine will do it’s task (printing the message in line 37).


If you like the article, please don’t forget to hit the love button
Note: I’ll try to update all of my articles in this series. To get update follow me on twitter or medium. One more thing, if you find any mistake or misleading in these articles please knock me or write a comment. Thank you
If you like my writing please follow me Saddam H.