What is Concurrency?

Orhun Onar
5 min readMar 21, 2022

--

Concurrency is the execution of parts of a concurrent program, algorithm or problem in computer science, without following a certain order, without changing the result. Thank you for reading. See you in the next article… Ah, it didn’t seem like much. Such things discourage people who are already dealing with computer science. Anyway, I don’t want to talk about the vulnerabilities of the education system here for now. Our topic: Concurrency. Concurrency is actually trying to do the things we want to do at the same time, regardless of the order. I think it would not be wrong if I gave a cliché example that I can have children and make a career. But it may lead to the purpose of our topic, so let me give a more logical example.

Let’s Understand Concurrency Better

I want to tell you the situation with the simplest example. To walk!. Yes, walking and Concurrency are very similar. You have to walk using both feet. First you take your left step, after that you take your next step, and they happen at the same time. This way you can walk.

What is Parallelism?

Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.-Rob Pike

Where did this come from, I hear you say now. Parallelism is also quite similar to Concurrency, but with a few minor differences, of course. In our example above, our job was to walk. Let our threads be our feet. First the left foot, then the right foot… Unless the mehter anthem is playing in the background 😊. In parallellisim, on the other hand, you run two threads, that is, both feet at the same time. So you jump like a rabbit… In this way, your two threads, namely your feet, do not have to wait for each other. But the most important difference is that the Concurrency method uses a single processor and Paralellism uses multi processors.

Differences between Concurrency and Parallelism

What are the Goroutines?

Are you bored? The most exciting part is just getting started. If you are more or less familiar with the Golang language, you may be familiar with the concept of Goroutines. A goroutine is a function that is capable of running concurrently with other functions. To create a goroutine we use the keyword go.
Now let’s try to fit the Goroutines to the example we made above.
In this example, we will print the right step and left step on the terminal screen. After the action is finished, we will print the action finished.

package mainimport (“fmt”“time”)func main() {for i := 0; i < 5; i++ {go func() {fmt.Println(i, “: Left Foot”)}()time.Sleep(time.Second)go func() {fmt.Println(i, “:Right Foot”)}()time.Sleep(time.Second)}time.Sleep(time.Second)fmt.Println(“Done”)}

Outputs are below:

0 : Left Foot
0 :Right Foot
1 : Left Foot
1 :Right Foot
2 : Left Foot
2 :Right Foot
3 : Left Foot
3 :Right Foot
4 : Left Foot
4 :Right Foot
Done

As you can see, 2 different goroutines are assigned for the right and left legs, and these threads are made to run waiting for each other. In this way, the act of walking was carried out.

What are the channels?

Aren’t we done with Concurrency yet? Actually, it’s partially finished, but there are a few more issues I want to talk about. One of them is Channels. Leaving aside television channels and water channels, channels in Golang allow us to communicate between goroutine

package mainimport “fmt”func main() {messages := make(chan string)go func() { messages <- “ping” }()msg := <-messages
fmt.Println(msg)
}

Output is below

ping

Send a value into a channel using the channel <- syntax. Here we send “ping” to the messages channel we made above, from a new goroutine.The <-channel syntax receives a value from the channel. Here we’ll receive the “ping” message we sent above and print it out. When we run the program the “ping” message is successfully passed from one goroutine to another via our channel.

What about the Deadlocks?

A Deadlock isa powerlifting exercise where you can develop your back muscles. Nope, that was Deadlift sorry!!! 😊. Deadlock is the problem that occurs when a group of goroutines are waiting for each other and none of them can advance. It looks like Barber Paradox doesn’t it? Let’s look at an example.

An Example of Deadlock
Another Kind of Deadlock
func main() {c1 := make(chan int)fmt.Println(“push c1: “)c1 <- 10g1 := <-c1fmt.Println(“get g1: “, g1)}

Output is below

push c1: 
fatal error: all goroutines are asleep — deadlock!
goroutine 1 [chan send]:

The reason of the deadlock is that we did not use any goroutine to prevent the deadlock.As a result, g1 read the c1 as an empty input even we gave it the value 10.

Then , how can we prevent the deadlock in the code?.Let’s take a look at the example below.

func main() {c1 := make(chan int)go func() {fmt.Println(“push c1 “)c1 <- 10}()time.Sleep(1 * time.Second)go func() {g1 := <-c1fmt.Println(“get g1: “, g1)}()time.Sleep(1 * time.Second)}

Output:

push c1 
get g1: 10

In this example, we put our variables under goroutines and prevented threads from interfering with each other’s work. Of course, we can use only single goroutine to prevent the deadlock like below

func main() {c1 := make(chan int)go func() {fmt.Println(“push c1 “)c1 <- 10}()time.Sleep(1 * time.Second)g1 := <-c1fmt.Println(“get g1: “, g1)time.Sleep(1 * time.Second)}

Output is the same as the previous one.

Conclusion

As a result, concurrency has a very important place in the Golang language, and thanks to Goroutines, we can have the opportunity to run our threads simultaneously.

--

--