Concurrency in Go

Tram Ho

1. Introduction

Concurrency is considered one of the most attractive features of Go to take advantage of the processing power of the CPU.

Concurrency is similar to Thread, in Go, the communication between goroutines is quite simple with channels , which can transfer data between goroutine with any type of data.

If a Java thread is created, it will use approximately 1MB of the heap memory, if you create 1,000 such threads, they will put a lot of pressure on the heap resulting in the system crashing because of a shortage. Memory, on the other hand, makes communication between two or more threads extremely difficult.

But Go is different, when using multi-core processors is feasible, Goroutines can completely replace Thread. Each Goroutines only uses 2KB of memory from Heap, so you can generate millions of goroutines at any time.

Go encourages an approach where each thread only accesses the shared value at a given time, and this shared value is passed between threads through the communication channel. It is conceivable that this mechanism is like running two single-threaded programs on a CPU and for the two programs to exchange information with each other, the information exchange process will play the role of synchronizing data between the two. this program.

This article will introduce the basic concepts of concurrency in Go.

2. Goroutine

Goroutine is a thread managed by Go runtime. It can be easily understood that goroutine is a function that runs concurrently with other functions.

The syntax of goroutine is very simple, we just need to add go before each function to call

Output:

In the above code, there are 2 goroutine functions, the first one is main () , the second is say () when called in go say (1, “hello, world.”) . If we call the say () function normally then when calling, the main () function will have to stop everything, wait for the say () function to finish its job and then return control to main () , the main () function continues its work.

You can create thousands of routines as well:

3. Channel

Channel is a feature that allows goroutines to exchange data with each other.

Channel is initialized with the following syntax:

They are used with operator <-

Specifically we come up with the following example:

In the above example, the send function transmits the value of i into channel c . The receive function receives the values ​​from channel c and assgin it for s and then prints it to the screen.

Output:

Using a channel allows synchronization of data between goroutines because when a goroutine transmits data to the channel, that goroutine will stop its programming and wait until another goroutine takes the data out of the channel and then it just continue.

In the above example, the send function transmits i = 0 into the channel, it will wait for the receive function to get that data out of the channel before continuing to transmit i = 1 into the channel.

4. Buffered Channel

As mentioned above, when goroutine transmits data into the channel, there must be another goroutine to get data out or vice versa, otherwise the goroutine will go into a “standby” state.

However, we can allow goroutine to not wait any longer by using buffered channels. Buffered Channel means that channel limits input. Still with the above example, we changed c := make(chan int) to c := make(chan int, 5) :

Output:

The send function keeps putting data into channel c without waiting for the receive function to retrieve it.

5. Channel Navigation

We can enable a read-only or write-only channel.

The line of code above specifies that the channel is only allowed to transmit data.

The line of code above specifies the channel to be read only.

6. Range and Close

The sender can close a channel to indicate that no additional values ​​will be sent:

The receiver can check if a channel is closed by assigning the second parameter to the expression as follows:

ok is false if there is no additional value to receive and the channel is closed.

The loop for i := range c receives values ​​from the channel continuously until it is closed.

For example:

Output:

7. Select

The syntax of select in Go is almost the same as the switch command

Output:

Channel c will be able to receive data after goroutine go func() retrieves the data: fmt.Println(<- c) . Channel quit will be blocked until data is sent into it.

In the above example, the fibonacci function will continually count the fibonacci sequence, sending the value of x into channel c until the channel quit receives the value.

This means that the select statement will execute a block of cases if the channel’s case is not blocked.

If there are several possible cases, one of them will be randomly selected:

The above example will print channel1 or channel2 randomly.

Similar to a switch , select also has a default case:

This is done when all other cases are blocked.

8. sync.Mutex

We have seen that channel is really a great feature for communicating between goroutines . But what if we don’t need the communication between them? How do multiple goroutines access the same resource?

When a program runs concurrently , code sharing resources cannot be accessed by multiple goroutines at the same time. Such code is called a critical section . For example, suppose we have the following code:

Ouput:

Obviously our wish is Final Count: 30 , because we have done count 30 times. But the result is only 13 . The reason is because the goroutines same access to the variable count lead to conflict.

Go provides Mutex in sync package to solve this problem.

Mutex stands for Mut ual Ex clusion. Means mutual exclusion. Understandably, the toilet has only one room, but both of them want to enter, of course, there will be a man who has to wait outside.

The method is quite simple, we just need to wrap the critical section block by two functions: Mutex.Lock() and Mutex.Unlock() :

Output:

9. Conclusion

Concurrency is an attractive and extremely powerful feature of Go. This article helps you understand the basic concepts of concurrency in Go such as: goroutine , channel , …

Hopefully the article will help new people who are in contact with Go better understand it. Remember to upvote yourself if you find the article useful! 😉

Share the news now

Source : Viblo