Hi.
We're back with the fifth video of this section Mew Texas.
In the previous video we learned how to use callbacks and go.
In this video will develop a small concurrent counter this counter will add one to an integer field
in a counter type.
This should be done in a concurrent safe way.
If you're working with concurrent applications you have to deal with more than one resource potentially
accessing some memory location.
This is usually called race condition.
In simpler terms a race condition is similar to that moment where two people tried to get the last piece
of pizza exactly the same time their hands clock replaced a pizza with a variable and their hands with
go routines and we'll have a perfect analogy.
There is one character at a dinner table to solve this issue.
A father or mother they've kept the pizza on a different table and we have to ask permission to stand
up before getting our slice of pizza.
It doesn't matter if all the kids ask at the same time they will only allow one kid to stand.
Well a new text is like our parents.
They'll control who can access the pizza.
I mean a variable and they won't allow anyone else to access it to use a new text.
We have to act to be Lochhead if it's already locked.
Another guy routine is using it would have to wait until it's unlocked again.
Once we get access to the new text we can lock it again do whatever modifications are needed and unlock
it again we'll look at this using example of a concurrent counter me text is all widely used in concurrent
programming.
Maybe not so much in go because it has a much more idiomatic way of concurrent programming and its use
of channels but it's worth seeing how they work for the situations where Channel simply don't fit so
well.
Let me show you how we define our counter structure.
I've already created the may not go far where we'll write the code let us have the code here the counter
structure has a field of int type that stores the current value of the account.
It also embeds the new takes type from the sync package embedding this field will allow us to lock and
unlock the entire structure without actively calling a specific field.
Our main function will launch 10 go routines that try to add one to the field value of Count structure.
All of this is done concurrently.
So next we add the main function so we need to import sync and time packages which we're using in the
main function okay.
Let's say the file we've created a type called counter using a for loop.
We've launched a total of 10 go routines as we saw in the anonymous functions launched as new guy routine
section but inside every go routine we're locking the counter so that no more go routines can access
it.
Adding 1 to the field value and unlocking against others can access it.
Finally will print the value held by the counter.
It must be 10 because we've launched 10 go routines.
But how can we know that this program is thread safe.
Well go comes with a very handy built in feature called the race detector so let's look into presenting
the race detector.
We already know what a race condition is.
To recap it's used when two processes tried to access the same resource at the same time with one or
more writing operations.
That is both processes writing or one process writing while another reads involved at that precise moment
go has a very handy tool to help diagnose race conditions that you can run in your tests or your main
application directly so let's reuse the example we just wrote for the new Texas section and run it with
the race detector.
This is as simple as adding the hyphen race command line flag to the command execution of our program
let's save the file and move on to the command line terminal and execute the command.
Go run hyphen race main dot go.
Well not very impressive is it but in fact it's telling us that he has not detected a potential race
condition in the code of the program let's make the detector of Hyphen race flag warnings of a possible
race condition by not locking counter before we modified.
Let's go back to the code file and make the changes we just need to modify the counter dot lock and
counter dot unlock as comments in our code now inside the for loop comment.
The lock and unlock calls before and after adding one to the field value.
This will introduce a race condition.
Let's run the same program again with the race flag activated save the file again and navigate to the
terminal let's execute the previous command again I've reduced the output a bit to see things more clearly
we can see a big uppercase message reading warning data race but this output is very easy to reason
with.
First it's telling us that some memory position represented by line 18 in our main dot go file is reading
some variable but there is also a right operation in line 18 of the same file.
This is because a plus plus operation requires a read of the current value and a right to add one to
it.
That's why the race condition is in the same line because every time it's executed it reads and writes
the field in the count structure but let's keep in mind that the race detective works at runtime it
doesn't analyze our code statically what does it mean.
It means that we can have a potential race condition in our design that the race detector will not detect.
Let's take an example of this.
Get back to the code file and replace the code.
Let me give the proper indentations.
Fine we will take all locks and unlocks from the code and launch a single guy routine to update the
value field.
Save the file and go to the terminal when we run the previous command again we have no warnings.
So the code is correct.
Well we know by design it's not we can raise the number of Go routines execute it to and see what happens.
Go back to the code file include the time package and make the changes to the for loop change.
I less than 1 2 I less than 2.
Also we need to add a small piece of code with the time dot sleep method along with the lock and unlock
calls now say the file and let's execute the program again now.
Yes the race condition is detected.
But what if we reduce the number of processes in use to just 1.
Will we have a race condition too.
Let's try this execute the command.
Go Max proxy equals one.
Go run hyphen race main dot go.
It seems that the race condition has been detected.
This is because these scheduler executed one go routine first and then the other.
So finally the race condition occurs with a higher number of Go routines.
It will also warn us about race condition even if only using one core.
So the race detector can help us to detect race conditions that are happening in our code but it won't
protect us from bad design that is not immediately executing race conditions.
A very useful feature that can save us from lots of headaches wonderful in this video.
We've seen how to work with new taxes in the next video.
We'll have a look at channels.